
kernel/kernel.elf：     文件格式 elf64-littleriscv


Disassembly of section .text:

0000000080000000 <_entry>:

.section .text.entry
.global _entry
_entry:
    # 设置栈指针（stack_top在链接脚本中定义）
    la sp, stack_top
    80000000:	00006117          	auipc	sp,0x6
    80000004:	11010113          	add	sp,sp,272 # 80006110 <ticks>

    # 清零BSS段
    la t0, _bss_start   # BSS段起始地址（链接脚本定义）
    80000008:	00005297          	auipc	t0,0x5
    8000000c:	f6828293          	add	t0,t0,-152 # 80004f70 <interrupt_handlers>
    la t1, _bss_end     # BSS段结束地址（链接脚本定义）
    80000010:	00005317          	auipc	t1,0x5
    80000014:	10030313          	add	t1,t1,256 # 80005110 <_bss_end>

0000000080000018 <bss_clear_loop>:
bss_clear_loop:
    bge t0, t1, bss_clear_done  # 若已到结束地址，退出循环
    80000018:	0062d663          	bge	t0,t1,80000024 <bss_clear_done>
    sb zero, 0(t0)              # 写入0
    8000001c:	00028023          	sb	zero,0(t0)
    addi t0, t0, 1              # 移动到下一个字节
    80000020:	0285                	add	t0,t0,1
    j bss_clear_loop
    80000022:	bfdd                	j	80000018 <bss_clear_loop>

0000000080000024 <bss_clear_done>:

    # 跳转到C主函数（main）
    # call main
    # 跳转到机器模式启动函数
    # start函数会设置中断委托，然后通过mret跳转到supervisor模式的main()
    call start
    80000024:	006000ef          	jal	8000002a <start>

0000000080000028 <spin>:

    # 若C主函数意外返回，进入死循环
spin:
    j spin
    80000028:	a001                	j	80000028 <spin>

000000008000002a <start>:
/*
 * 机器模式启动函数
 * 在entry.S中被调用
 */
void start(void)
{
    8000002a:	1141                	add	sp,sp,-16
    8000002c:	e422                	sd	s0,8(sp)
    8000002e:	0800                	add	s0,sp,16
    // 设置M Previous Privilege mode为Supervisor，用于mret
    uint64 x = r_mstatus();
    80000030:	300027f3          	csrr	a5,mstatus
    x &= ~MSTATUS_MPP_MASK;
    80000034:	7779                	lui	a4,0xffffe
    80000036:	7ff70713          	add	a4,a4,2047 # ffffffffffffe7ff <tests_passed+0xffffffff7fff86cb>
    8000003a:	8ff9                	and	a5,a5,a4
    x |= MSTATUS_MPP_S;
    8000003c:	6705                	lui	a4,0x1
    8000003e:	80070713          	add	a4,a4,-2048 # 800 <_entry-0x7ffff800>
    80000042:	8fd9                	or	a5,a5,a4
    w_mstatus(x);
    80000044:	30079073          	csrw	mstatus,a5

    // 设置M Exception Program Counter为main，用于mret
    w_mepc((uint64)main);
    80000048:	00001797          	auipc	a5,0x1
    8000004c:	99a78793          	add	a5,a5,-1638 # 800009e2 <main>
    80000050:	34179073          	csrw	mepc,a5

    // 禁用分页
    asm volatile("csrw satp, zero");
    80000054:	18001073          	csrw	satp,zero

    // 将所有中断和异常委托给supervisor模式
    w_medeleg(0xffff);
    80000058:	67c1                	lui	a5,0x10
    8000005a:	37fd                	addw	a5,a5,-1 # ffff <_entry-0x7fff0001>
    8000005c:	30279073          	csrw	medeleg,a5
    w_mideleg(0xffff);
    80000060:	30379073          	csrw	mideleg,a5

    // 配置物理内存保护，给supervisor模式访问所有物理内存的权限
    // PMP地址寄存器0设置为最大地址
    asm volatile("csrw pmpaddr0, %0" : : "r" (0x3fffffffffffffull));
    80000064:	57fd                	li	a5,-1
    80000066:	83a9                	srl	a5,a5,0xa
    80000068:	3b079073          	csrw	pmpaddr0,a5
    // PMP配置寄存器0设置为读写执行权限
    asm volatile("csrw pmpcfg0, %0" : : "r" (0xf));
    8000006c:	47bd                	li	a5,15
    8000006e:	3a079073          	csrw	pmpcfg0,a5

    // 保存hart id到tp寄存器
    int id = r_mhartid();
    80000072:	f14027f3          	csrr	a5,mhartid
    asm volatile("mv tp, %0" : : "r" (id));
    80000076:	823e                	mv	tp,a5

    // 切换到supervisor模式并跳转到main()
    asm volatile("mret");
    80000078:	30200073          	mret
}
    8000007c:	6422                	ld	s0,8(sp)
    8000007e:	0141                	add	sp,sp,16
    80000080:	8082                	ret

0000000080000082 <timerinit>:

/*
 * 请求每个hart生成时钟中断
 */
void timerinit(void)
{
    80000082:	1141                	add	sp,sp,-16
    80000084:	e422                	sd	s0,8(sp)
    80000086:	0800                	add	s0,sp,16
    // 简化的时钟初始化
    // 在supervisor模式下初始化时钟
    80000088:	6422                	ld	s0,8(sp)
    8000008a:	0141                	add	sp,sp,16
    8000008c:	8082                	ret

000000008000008e <timer_interrupt>:
 * 时钟中断处理
 */
void timer_interrupt(void)
{
    // 增加系统时钟计数
    ticks++;
    8000008e:	00006797          	auipc	a5,0x6
    80000092:	08278793          	add	a5,a5,130 # 80006110 <ticks>
    80000096:	638c                	ld	a1,0(a5)
    80000098:	0585                	add	a1,a1,1
    8000009a:	e38c                	sd	a1,0(a5)
    
    // 设置下次时钟中断
    set_next_timer();
    
    // 每100个时钟周期打印一次（可选）
    if (ticks % 100 == 0) {
    8000009c:	06400793          	li	a5,100
    800000a0:	02f5f7b3          	remu	a5,a1,a5
    800000a4:	c391                	beqz	a5,800000a8 <timer_interrupt+0x1a>
    800000a6:	8082                	ret
{
    800000a8:	1141                	add	sp,sp,-16
    800000aa:	e406                	sd	ra,8(sp)
    800000ac:	e022                	sd	s0,0(sp)
    800000ae:	0800                	add	s0,sp,16
        printf("Timer tick: %ld\n", ticks);
    800000b0:	00003517          	auipc	a0,0x3
    800000b4:	f5050513          	add	a0,a0,-176 # 80003000 <etext>
    800000b8:	6dd000ef          	jal	80000f94 <printf>
    }
}
    800000bc:	60a2                	ld	ra,8(sp)
    800000be:	6402                	ld	s0,0(sp)
    800000c0:	0141                	add	sp,sp,16
    800000c2:	8082                	ret

00000000800000c4 <trap_init_hart>:
{
    800000c4:	1141                	add	sp,sp,-16
    800000c6:	e406                	sd	ra,8(sp)
    800000c8:	e022                	sd	s0,0(sp)
    800000ca:	0800                	add	s0,sp,16
    w_stvec((uint64)kernelvec);
    800000cc:	00000797          	auipc	a5,0x0
    800000d0:	42478793          	add	a5,a5,1060 # 800004f0 <kernelvec>
    800000d4:	10579073          	csrw	stvec,a5
    w_sie(r_sie() | SIE_STIE);
    800000d8:	104027f3          	csrr	a5,sie
    800000dc:	0207e793          	or	a5,a5,32
    800000e0:	10479073          	csrw	sie,a5
#define w_mideleg(x) asm volatile("csrw mideleg, %0" : : "r" (x))

// 中断控制函数
static inline void intr_on(void)
{
    w_sstatus(r_sstatus() | SSTATUS_SIE);
    800000e4:	100027f3          	csrr	a5,sstatus
    800000e8:	0027e793          	or	a5,a5,2
    800000ec:	10079073          	csrw	sstatus,a5
    printf("Hart trap initialized.\n");
    800000f0:	00003517          	auipc	a0,0x3
    800000f4:	f2850513          	add	a0,a0,-216 # 80003018 <etext+0x18>
    800000f8:	69d000ef          	jal	80000f94 <printf>
}
    800000fc:	60a2                	ld	ra,8(sp)
    800000fe:	6402                	ld	s0,0(sp)
    80000100:	0141                	add	sp,sp,16
    80000102:	8082                	ret

0000000080000104 <register_interrupt>:
    if (irq >= 0 && irq < MAX_IRQ_NUM) {
    80000104:	47fd                	li	a5,31
    80000106:	00a7f363          	bgeu	a5,a0,8000010c <register_interrupt+0x8>
    8000010a:	8082                	ret
{
    8000010c:	1141                	add	sp,sp,-16
    8000010e:	e406                	sd	ra,8(sp)
    80000110:	e022                	sd	s0,0(sp)
    80000112:	0800                	add	s0,sp,16
        interrupt_handlers[irq] = handler;
    80000114:	00351693          	sll	a3,a0,0x3
    80000118:	00005797          	auipc	a5,0x5
    8000011c:	e5878793          	add	a5,a5,-424 # 80004f70 <interrupt_handlers>
    80000120:	97b6                	add	a5,a5,a3
    80000122:	e38c                	sd	a1,0(a5)
        printf("Registered interrupt handler for IRQ %d\n", irq);
    80000124:	85aa                	mv	a1,a0
    80000126:	00003517          	auipc	a0,0x3
    8000012a:	f0a50513          	add	a0,a0,-246 # 80003030 <etext+0x30>
    8000012e:	667000ef          	jal	80000f94 <printf>
}
    80000132:	60a2                	ld	ra,8(sp)
    80000134:	6402                	ld	s0,0(sp)
    80000136:	0141                	add	sp,sp,16
    80000138:	8082                	ret

000000008000013a <trap_init>:
{
    8000013a:	1141                	add	sp,sp,-16
    8000013c:	e406                	sd	ra,8(sp)
    8000013e:	e022                	sd	s0,0(sp)
    80000140:	0800                	add	s0,sp,16
    printf("Initializing trap system...\n");
    80000142:	00003517          	auipc	a0,0x3
    80000146:	f1e50513          	add	a0,a0,-226 # 80003060 <etext+0x60>
    8000014a:	64b000ef          	jal	80000f94 <printf>
    for (int i = 0; i < MAX_IRQ_NUM; i++) {
    8000014e:	00005797          	auipc	a5,0x5
    80000152:	e2278793          	add	a5,a5,-478 # 80004f70 <interrupt_handlers>
    80000156:	00005717          	auipc	a4,0x5
    8000015a:	f1a70713          	add	a4,a4,-230 # 80005070 <exception_handlers>
        interrupt_handlers[i] = 0;
    8000015e:	0007b023          	sd	zero,0(a5)
    for (int i = 0; i < MAX_IRQ_NUM; i++) {
    80000162:	07a1                	add	a5,a5,8
    80000164:	fee79de3          	bne	a5,a4,8000015e <trap_init+0x24>
    80000168:	00005797          	auipc	a5,0x5
    8000016c:	f0878793          	add	a5,a5,-248 # 80005070 <exception_handlers>
    80000170:	00005717          	auipc	a4,0x5
    80000174:	f8070713          	add	a4,a4,-128 # 800050f0 <kmem>
        exception_handlers[i] = 0;
    80000178:	0007b023          	sd	zero,0(a5)
    for (int i = 0; i < 16; i++) {
    8000017c:	07a1                	add	a5,a5,8
    8000017e:	fee79de3          	bne	a5,a4,80000178 <trap_init+0x3e>
    register_interrupt(IRQ_S_TIMER, timer_interrupt);
    80000182:	00000597          	auipc	a1,0x0
    80000186:	f0c58593          	add	a1,a1,-244 # 8000008e <timer_interrupt>
    8000018a:	4515                	li	a0,5
    8000018c:	f79ff0ef          	jal	80000104 <register_interrupt>
    printf("Trap system initialized.\n");
    80000190:	00003517          	auipc	a0,0x3
    80000194:	ef050513          	add	a0,a0,-272 # 80003080 <etext+0x80>
    80000198:	5fd000ef          	jal	80000f94 <printf>
}
    8000019c:	60a2                	ld	ra,8(sp)
    8000019e:	6402                	ld	s0,0(sp)
    800001a0:	0141                	add	sp,sp,16
    800001a2:	8082                	ret

00000000800001a4 <register_exception>:
    if (cause >= 0 && cause < 16) {
    800001a4:	47bd                	li	a5,15
    800001a6:	00a7f363          	bgeu	a5,a0,800001ac <register_exception+0x8>
    800001aa:	8082                	ret
{
    800001ac:	1141                	add	sp,sp,-16
    800001ae:	e406                	sd	ra,8(sp)
    800001b0:	e022                	sd	s0,0(sp)
    800001b2:	0800                	add	s0,sp,16
        exception_handlers[cause] = handler;
    800001b4:	00351693          	sll	a3,a0,0x3
    800001b8:	00005797          	auipc	a5,0x5
    800001bc:	db878793          	add	a5,a5,-584 # 80004f70 <interrupt_handlers>
    800001c0:	97b6                	add	a5,a5,a3
    800001c2:	10b7b023          	sd	a1,256(a5)
        printf("Registered exception handler for cause %d\n", cause);
    800001c6:	85aa                	mv	a1,a0
    800001c8:	00003517          	auipc	a0,0x3
    800001cc:	ed850513          	add	a0,a0,-296 # 800030a0 <etext+0xa0>
    800001d0:	5c5000ef          	jal	80000f94 <printf>
}
    800001d4:	60a2                	ld	ra,8(sp)
    800001d6:	6402                	ld	s0,0(sp)
    800001d8:	0141                	add	sp,sp,16
    800001da:	8082                	ret

00000000800001dc <enable_interrupt>:
{
    800001dc:	1141                	add	sp,sp,-16
    800001de:	e422                	sd	s0,8(sp)
    800001e0:	0800                	add	s0,sp,16
    uint64 sie = r_sie();
    800001e2:	104027f3          	csrr	a5,sie
    switch (irq) {
    800001e6:	4715                	li	a4,5
    800001e8:	00e50d63          	beq	a0,a4,80000202 <enable_interrupt+0x26>
    800001ec:	4725                	li	a4,9
    800001ee:	00e50d63          	beq	a0,a4,80000208 <enable_interrupt+0x2c>
    800001f2:	4705                	li	a4,1
    800001f4:	00e50d63          	beq	a0,a4,8000020e <enable_interrupt+0x32>
    w_sie(sie);
    800001f8:	10479073          	csrw	sie,a5
}
    800001fc:	6422                	ld	s0,8(sp)
    800001fe:	0141                	add	sp,sp,16
    80000200:	8082                	ret
            sie |= SIE_STIE;
    80000202:	0207e793          	or	a5,a5,32
            break;
    80000206:	bfcd                	j	800001f8 <enable_interrupt+0x1c>
            sie |= SIE_SEIE;
    80000208:	2007e793          	or	a5,a5,512
            break;
    8000020c:	b7f5                	j	800001f8 <enable_interrupt+0x1c>
            sie |= SIE_SSIE;
    8000020e:	0027e793          	or	a5,a5,2
            break;
    80000212:	b7dd                	j	800001f8 <enable_interrupt+0x1c>

0000000080000214 <disable_interrupt>:
{
    80000214:	1141                	add	sp,sp,-16
    80000216:	e422                	sd	s0,8(sp)
    80000218:	0800                	add	s0,sp,16
    uint64 sie = r_sie();
    8000021a:	104027f3          	csrr	a5,sie
    switch (irq) {
    8000021e:	4715                	li	a4,5
    80000220:	00e50d63          	beq	a0,a4,8000023a <disable_interrupt+0x26>
    80000224:	4725                	li	a4,9
    80000226:	00e50d63          	beq	a0,a4,80000240 <disable_interrupt+0x2c>
    8000022a:	4705                	li	a4,1
    8000022c:	00e50d63          	beq	a0,a4,80000246 <disable_interrupt+0x32>
    w_sie(sie);
    80000230:	10479073          	csrw	sie,a5
}
    80000234:	6422                	ld	s0,8(sp)
    80000236:	0141                	add	sp,sp,16
    80000238:	8082                	ret
            sie &= ~SIE_STIE;
    8000023a:	fdf7f793          	and	a5,a5,-33
            break;
    8000023e:	bfcd                	j	80000230 <disable_interrupt+0x1c>
            sie &= ~SIE_SEIE;
    80000240:	dff7f793          	and	a5,a5,-513
            break;
    80000244:	b7f5                	j	80000230 <disable_interrupt+0x1c>
            sie &= ~SIE_SSIE;
    80000246:	9bf5                	and	a5,a5,-3
            break;
    80000248:	b7e5                	j	80000230 <disable_interrupt+0x1c>

000000008000024a <devintr>:
    uint64 scause = r_scause();
    8000024a:	142027f3          	csrr	a5,scause
        return 0;
    8000024e:	4501                	li	a0,0
    if ((scause & 0x8000000000000000L) && (scause & 0xff) == 9) {
    80000250:	0007c363          	bltz	a5,80000256 <devintr+0xc>
}
    80000254:	8082                	ret
{
    80000256:	1141                	add	sp,sp,-16
    80000258:	e406                	sd	ra,8(sp)
    8000025a:	e022                	sd	s0,0(sp)
    8000025c:	0800                	add	s0,sp,16
    if ((scause & 0x8000000000000000L) && (scause & 0xff) == 9) {
    8000025e:	0ff7f793          	zext.b	a5,a5
    80000262:	4725                	li	a4,9
    80000264:	00e78d63          	beq	a5,a4,8000027e <devintr+0x34>
    } else if ((scause & 0x8000000000000000L) && (scause & 0xff) == 5) {
    80000268:	4715                	li	a4,5
    8000026a:	02e78263          	beq	a5,a4,8000028e <devintr+0x44>
    } else if ((scause & 0x8000000000000000L) && (scause & 0xff) == 1) {
    8000026e:	4705                	li	a4,1
        return 0;
    80000270:	4501                	li	a0,0
    } else if ((scause & 0x8000000000000000L) && (scause & 0xff) == 1) {
    80000272:	02e78763          	beq	a5,a4,800002a0 <devintr+0x56>
}
    80000276:	60a2                	ld	ra,8(sp)
    80000278:	6402                	ld	s0,0(sp)
    8000027a:	0141                	add	sp,sp,16
    8000027c:	8082                	ret
        printf("External interrupt\n");
    8000027e:	00003517          	auipc	a0,0x3
    80000282:	e5250513          	add	a0,a0,-430 # 800030d0 <etext+0xd0>
    80000286:	50f000ef          	jal	80000f94 <printf>
        return 1;
    8000028a:	4505                	li	a0,1
    8000028c:	b7ed                	j	80000276 <devintr+0x2c>
        if (interrupt_handlers[IRQ_S_TIMER]) {
    8000028e:	00005797          	auipc	a5,0x5
    80000292:	d0a7b783          	ld	a5,-758(a5) # 80004f98 <interrupt_handlers+0x28>
        return 2;
    80000296:	4509                	li	a0,2
        if (interrupt_handlers[IRQ_S_TIMER]) {
    80000298:	dff9                	beqz	a5,80000276 <devintr+0x2c>
            interrupt_handlers[IRQ_S_TIMER]();
    8000029a:	9782                	jalr	a5
        return 2;
    8000029c:	4509                	li	a0,2
    8000029e:	bfe1                	j	80000276 <devintr+0x2c>
        printf("Software interrupt\n");
    800002a0:	00003517          	auipc	a0,0x3
    800002a4:	e4850513          	add	a0,a0,-440 # 800030e8 <etext+0xe8>
    800002a8:	4ed000ef          	jal	80000f94 <printf>
        return 3;
    800002ac:	450d                	li	a0,3
    800002ae:	b7e1                	j	80000276 <devintr+0x2c>

00000000800002b0 <set_next_timer>:

/*
 * 设置下次时钟中断
 */
void set_next_timer(void)
{
    800002b0:	1141                	add	sp,sp,-16
    800002b2:	e422                	sd	s0,8(sp)
    800002b4:	0800                	add	s0,sp,16
    // 简化版本，暂时不设置时钟中断
    // sbi_set_timer(r_time() + TIMER_INTERVAL);
}
    800002b6:	6422                	ld	s0,8(sp)
    800002b8:	0141                	add	sp,sp,16
    800002ba:	8082                	ret

00000000800002bc <timer_init>:

/*
 * 初始化时钟
 */
void timer_init(void)
{
    800002bc:	1141                	add	sp,sp,-16
    800002be:	e406                	sd	ra,8(sp)
    800002c0:	e022                	sd	s0,0(sp)
    800002c2:	0800                	add	s0,sp,16
    printf("Initializing timer...\n");
    800002c4:	00003517          	auipc	a0,0x3
    800002c8:	e3c50513          	add	a0,a0,-452 # 80003100 <etext+0x100>
    800002cc:	4c9000ef          	jal	80000f94 <printf>
    
    // 简化版本，暂时不设置时钟中断
    // set_next_timer();
    
    printf("Timer initialized.\n");
    800002d0:	00003517          	auipc	a0,0x3
    800002d4:	e4850513          	add	a0,a0,-440 # 80003118 <etext+0x118>
    800002d8:	4bd000ef          	jal	80000f94 <printf>
}
    800002dc:	60a2                	ld	ra,8(sp)
    800002de:	6402                	ld	s0,0(sp)
    800002e0:	0141                	add	sp,sp,16
    800002e2:	8082                	ret

00000000800002e4 <syscall>:

/*
 * 系统调用处理（简化版）
 */
void syscall(void)
{
    800002e4:	1141                	add	sp,sp,-16
    800002e6:	e406                	sd	ra,8(sp)
    800002e8:	e022                	sd	s0,0(sp)
    800002ea:	0800                	add	s0,sp,16
    printf("System call not implemented yet\n");
    800002ec:	00003517          	auipc	a0,0x3
    800002f0:	e4450513          	add	a0,a0,-444 # 80003130 <etext+0x130>
    800002f4:	4a1000ef          	jal	80000f94 <printf>
}
    800002f8:	60a2                	ld	ra,8(sp)
    800002fa:	6402                	ld	s0,0(sp)
    800002fc:	0141                	add	sp,sp,16
    800002fe:	8082                	ret

0000000080000300 <handle_exception>:
{
    80000300:	7179                	add	sp,sp,-48
    80000302:	f406                	sd	ra,40(sp)
    80000304:	f022                	sd	s0,32(sp)
    80000306:	ec26                	sd	s1,24(sp)
    80000308:	e84a                	sd	s2,16(sp)
    8000030a:	e44e                	sd	s3,8(sp)
    8000030c:	1800                	add	s0,sp,48
    8000030e:	84aa                	mv	s1,a0
    80000310:	892e                	mv	s2,a1
    80000312:	89b2                	mv	s3,a2
    printf("Exception: cause=0x%lx, epc=0x%lx, tval=0x%lx\n", cause, epc, tval);
    80000314:	86b2                	mv	a3,a2
    80000316:	862e                	mv	a2,a1
    80000318:	85aa                	mv	a1,a0
    8000031a:	00003517          	auipc	a0,0x3
    8000031e:	e3e50513          	add	a0,a0,-450 # 80003158 <etext+0x158>
    80000322:	473000ef          	jal	80000f94 <printf>
    if (cause < 16 && exception_handlers[cause]) {
    80000326:	47bd                	li	a5,15
    80000328:	1097e163          	bltu	a5,s1,8000042a <handle_exception+0x12a>
    8000032c:	00349713          	sll	a4,s1,0x3
    80000330:	00005797          	auipc	a5,0x5
    80000334:	c4078793          	add	a5,a5,-960 # 80004f70 <interrupt_handlers>
    80000338:	97ba                	add	a5,a5,a4
    8000033a:	1007b783          	ld	a5,256(a5)
    8000033e:	cf81                	beqz	a5,80000356 <handle_exception+0x56>
        exception_handlers[cause](cause, epc, tval);
    80000340:	864e                	mv	a2,s3
    80000342:	85ca                	mv	a1,s2
    80000344:	8526                	mv	a0,s1
    80000346:	9782                	jalr	a5
}
    80000348:	70a2                	ld	ra,40(sp)
    8000034a:	7402                	ld	s0,32(sp)
    8000034c:	64e2                	ld	s1,24(sp)
    8000034e:	6942                	ld	s2,16(sp)
    80000350:	69a2                	ld	s3,8(sp)
    80000352:	6145                	add	sp,sp,48
    80000354:	8082                	ret
    switch (cause) {
    80000356:	47bd                	li	a5,15
    80000358:	0c97e963          	bltu	a5,s1,8000042a <handle_exception+0x12a>
    8000035c:	00249793          	sll	a5,s1,0x2
    80000360:	00003717          	auipc	a4,0x3
    80000364:	00070713          	mv	a4,a4
    80000368:	97ba                	add	a5,a5,a4
    8000036a:	439c                	lw	a5,0(a5)
    8000036c:	97ba                	add	a5,a5,a4
    8000036e:	8782                	jr	a5
            printf("Instruction address misaligned\n");
    80000370:	00003517          	auipc	a0,0x3
    80000374:	e1850513          	add	a0,a0,-488 # 80003188 <etext+0x188>
    80000378:	41d000ef          	jal	80000f94 <printf>
            break;
    8000037c:	a875                	j	80000438 <handle_exception+0x138>
            printf("Instruction access fault\n");
    8000037e:	00003517          	auipc	a0,0x3
    80000382:	e2a50513          	add	a0,a0,-470 # 800031a8 <etext+0x1a8>
    80000386:	40f000ef          	jal	80000f94 <printf>
            break;
    8000038a:	a07d                	j	80000438 <handle_exception+0x138>
            printf("Illegal instruction\n");
    8000038c:	00003517          	auipc	a0,0x3
    80000390:	e3c50513          	add	a0,a0,-452 # 800031c8 <etext+0x1c8>
    80000394:	401000ef          	jal	80000f94 <printf>
            break;
    80000398:	a045                	j	80000438 <handle_exception+0x138>
            printf("Breakpoint\n");
    8000039a:	00003517          	auipc	a0,0x3
    8000039e:	e4650513          	add	a0,a0,-442 # 800031e0 <etext+0x1e0>
    800003a2:	3f3000ef          	jal	80000f94 <printf>
            break;
    800003a6:	a849                	j	80000438 <handle_exception+0x138>
            printf("Load address misaligned\n");
    800003a8:	00003517          	auipc	a0,0x3
    800003ac:	e4850513          	add	a0,a0,-440 # 800031f0 <etext+0x1f0>
    800003b0:	3e5000ef          	jal	80000f94 <printf>
            break;
    800003b4:	a051                	j	80000438 <handle_exception+0x138>
            printf("Load access fault\n");
    800003b6:	00003517          	auipc	a0,0x3
    800003ba:	e5a50513          	add	a0,a0,-422 # 80003210 <etext+0x210>
    800003be:	3d7000ef          	jal	80000f94 <printf>
            break;
    800003c2:	a89d                	j	80000438 <handle_exception+0x138>
            printf("Store address misaligned\n");
    800003c4:	00003517          	auipc	a0,0x3
    800003c8:	e6450513          	add	a0,a0,-412 # 80003228 <etext+0x228>
    800003cc:	3c9000ef          	jal	80000f94 <printf>
            break;
    800003d0:	a0a5                	j	80000438 <handle_exception+0x138>
            printf("Store access fault\n");
    800003d2:	00003517          	auipc	a0,0x3
    800003d6:	e7650513          	add	a0,a0,-394 # 80003248 <etext+0x248>
    800003da:	3bb000ef          	jal	80000f94 <printf>
            break;
    800003de:	a8a9                	j	80000438 <handle_exception+0x138>
            printf("User environment call\n");
    800003e0:	00003517          	auipc	a0,0x3
    800003e4:	e8050513          	add	a0,a0,-384 # 80003260 <etext+0x260>
    800003e8:	3ad000ef          	jal	80000f94 <printf>
            syscall();
    800003ec:	ef9ff0ef          	jal	800002e4 <syscall>
            break;
    800003f0:	a0a1                	j	80000438 <handle_exception+0x138>
            printf("Supervisor environment call\n");
    800003f2:	00003517          	auipc	a0,0x3
    800003f6:	e8650513          	add	a0,a0,-378 # 80003278 <etext+0x278>
    800003fa:	39b000ef          	jal	80000f94 <printf>
            break;
    800003fe:	a82d                	j	80000438 <handle_exception+0x138>
            printf("Instruction page fault\n");
    80000400:	00003517          	auipc	a0,0x3
    80000404:	e9850513          	add	a0,a0,-360 # 80003298 <etext+0x298>
    80000408:	38d000ef          	jal	80000f94 <printf>
            break;
    8000040c:	a035                	j	80000438 <handle_exception+0x138>
            printf("Load page fault\n");
    8000040e:	00003517          	auipc	a0,0x3
    80000412:	ea250513          	add	a0,a0,-350 # 800032b0 <etext+0x2b0>
    80000416:	37f000ef          	jal	80000f94 <printf>
            break;
    8000041a:	a839                	j	80000438 <handle_exception+0x138>
            printf("Store page fault\n");
    8000041c:	00003517          	auipc	a0,0x3
    80000420:	eac50513          	add	a0,a0,-340 # 800032c8 <etext+0x2c8>
    80000424:	371000ef          	jal	80000f94 <printf>
            break;
    80000428:	a801                	j	80000438 <handle_exception+0x138>
            printf("Unknown exception: %ld\n", cause);
    8000042a:	85a6                	mv	a1,s1
    8000042c:	00003517          	auipc	a0,0x3
    80000430:	eb450513          	add	a0,a0,-332 # 800032e0 <etext+0x2e0>
    80000434:	361000ef          	jal	80000f94 <printf>
    printf("System halted due to exception\n");
    80000438:	00003517          	auipc	a0,0x3
    8000043c:	ec050513          	add	a0,a0,-320 # 800032f8 <etext+0x2f8>
    80000440:	355000ef          	jal	80000f94 <printf>
        asm volatile("wfi"); // 等待中断
    80000444:	10500073          	wfi
    while (1) {
    80000448:	bff5                	j	80000444 <handle_exception+0x144>

000000008000044a <kerneltrap>:
{
    8000044a:	1101                	add	sp,sp,-32
    8000044c:	ec06                	sd	ra,24(sp)
    8000044e:	e822                	sd	s0,16(sp)
    80000450:	e426                	sd	s1,8(sp)
    80000452:	e04a                	sd	s2,0(sp)
    80000454:	1000                	add	s0,sp,32
    uint64 sepc = r_sepc();
    80000456:	14102973          	csrr	s2,sepc
    uint64 sstatus = r_sstatus();
    8000045a:	100024f3          	csrr	s1,sstatus
    uint64 scause = r_scause();
    8000045e:	14202573          	csrr	a0,scause
    if ((sstatus & SSTATUS_SPP) == 0) {
    80000462:	1004f793          	and	a5,s1,256
    80000466:	c795                	beqz	a5,80000492 <kerneltrap+0x48>
    w_sstatus(r_sstatus() & ~SSTATUS_SIE);
}

static inline int intr_get(void)
{
    uint64 x = r_sstatus();
    80000468:	100027f3          	csrr	a5,sstatus
    return (x & SSTATUS_SIE) != 0;
    8000046c:	8b89                	and	a5,a5,2
    if (intr_get() != 0) {
    8000046e:	eb8d                	bnez	a5,800004a0 <kerneltrap+0x56>
    if ((scause & 0x8000000000000000L) != 0) {
    80000470:	02054f63          	bltz	a0,800004ae <kerneltrap+0x64>
        handle_exception(scause, sepc, r_stval());
    80000474:	14302673          	csrr	a2,stval
    80000478:	85ca                	mv	a1,s2
    8000047a:	e87ff0ef          	jal	80000300 <handle_exception>
    w_sepc(sepc);
    8000047e:	14191073          	csrw	sepc,s2
    w_sstatus(sstatus);
    80000482:	10049073          	csrw	sstatus,s1
}
    80000486:	60e2                	ld	ra,24(sp)
    80000488:	6442                	ld	s0,16(sp)
    8000048a:	64a2                	ld	s1,8(sp)
    8000048c:	6902                	ld	s2,0(sp)
    8000048e:	6105                	add	sp,sp,32
    80000490:	8082                	ret
        printf("kerneltrap: not from supervisor mode\n");
    80000492:	00003517          	auipc	a0,0x3
    80000496:	e8650513          	add	a0,a0,-378 # 80003318 <etext+0x318>
    8000049a:	2fb000ef          	jal	80000f94 <printf>
        return;
    8000049e:	b7e5                	j	80000486 <kerneltrap+0x3c>
        printf("kerneltrap: interrupts enabled\n");
    800004a0:	00003517          	auipc	a0,0x3
    800004a4:	ea050513          	add	a0,a0,-352 # 80003340 <etext+0x340>
    800004a8:	2ed000ef          	jal	80000f94 <printf>
        return;
    800004ac:	bfe9                	j	80000486 <kerneltrap+0x3c>
        devintr();
    800004ae:	d9dff0ef          	jal	8000024a <devintr>
    800004b2:	b7f1                	j	8000047e <kerneltrap+0x34>

00000000800004b4 <usertrap>:
{
    800004b4:	1141                	add	sp,sp,-16
    800004b6:	e406                	sd	ra,8(sp)
    800004b8:	e022                	sd	s0,0(sp)
    800004ba:	0800                	add	s0,sp,16
    uint64 scause = r_scause();
    800004bc:	14202573          	csrr	a0,scause
    w_stvec((uint64)kernelvec);
    800004c0:	00000797          	auipc	a5,0x0
    800004c4:	03078793          	add	a5,a5,48 # 800004f0 <kernelvec>
    800004c8:	10579073          	csrw	stvec,a5
    if ((scause & 0x8000000000000000L) != 0) {
    800004cc:	00054d63          	bltz	a0,800004e6 <usertrap+0x32>
        handle_exception(scause, r_sepc(), r_stval());
    800004d0:	141025f3          	csrr	a1,sepc
    800004d4:	14302673          	csrr	a2,stval
    800004d8:	e29ff0ef          	jal	80000300 <handle_exception>
}
    800004dc:	4501                	li	a0,0
    800004de:	60a2                	ld	ra,8(sp)
    800004e0:	6402                	ld	s0,0(sp)
    800004e2:	0141                	add	sp,sp,16
    800004e4:	8082                	ret
        devintr();
    800004e6:	d65ff0ef          	jal	8000024a <devintr>
    800004ea:	bfcd                	j	800004dc <usertrap+0x28>
    800004ec:	0000                	unimp
	...

00000000800004f0 <kernelvec>:
.globl kernelvec
.align 4
kernelvec:
        # 为保存寄存器腾出栈空间
        # 需要保存32个寄存器，每个8字节，共256字节
        addi sp, sp, -256
    800004f0:	7111                	add	sp,sp,-256

        # 保存调用者保存的寄存器
        # 不保存sp，因为我们正在使用它
        sd ra, 0(sp)
    800004f2:	e006                	sd	ra,0(sp)
        sd gp, 16(sp)
    800004f4:	e80e                	sd	gp,16(sp)
        sd tp, 24(sp)
    800004f6:	ec12                	sd	tp,24(sp)
        sd t0, 32(sp)
    800004f8:	f016                	sd	t0,32(sp)
        sd t1, 40(sp)
    800004fa:	f41a                	sd	t1,40(sp)
        sd t2, 48(sp)
    800004fc:	f81e                	sd	t2,48(sp)
        sd s0, 56(sp)
    800004fe:	fc22                	sd	s0,56(sp)
        sd s1, 64(sp)
    80000500:	e0a6                	sd	s1,64(sp)
        sd a0, 72(sp)
    80000502:	e4aa                	sd	a0,72(sp)
        sd a1, 80(sp)
    80000504:	e8ae                	sd	a1,80(sp)
        sd a2, 88(sp)
    80000506:	ecb2                	sd	a2,88(sp)
        sd a3, 96(sp)
    80000508:	f0b6                	sd	a3,96(sp)
        sd a4, 104(sp)
    8000050a:	f4ba                	sd	a4,104(sp)
        sd a5, 112(sp)
    8000050c:	f8be                	sd	a5,112(sp)
        sd a6, 120(sp)
    8000050e:	fcc2                	sd	a6,120(sp)
        sd a7, 128(sp)
    80000510:	e146                	sd	a7,128(sp)
        sd s2, 136(sp)
    80000512:	e54a                	sd	s2,136(sp)
        sd s3, 144(sp)
    80000514:	e94e                	sd	s3,144(sp)
        sd s4, 152(sp)
    80000516:	ed52                	sd	s4,152(sp)
        sd s5, 160(sp)
    80000518:	f156                	sd	s5,160(sp)
        sd s6, 168(sp)
    8000051a:	f55a                	sd	s6,168(sp)
        sd s7, 176(sp)
    8000051c:	f95e                	sd	s7,176(sp)
        sd s8, 184(sp)
    8000051e:	fd62                	sd	s8,184(sp)
        sd s9, 192(sp)
    80000520:	e1e6                	sd	s9,192(sp)
        sd s10, 200(sp)
    80000522:	e5ea                	sd	s10,200(sp)
        sd s11, 208(sp)
    80000524:	e9ee                	sd	s11,208(sp)
        sd t3, 216(sp)
    80000526:	edf2                	sd	t3,216(sp)
        sd t4, 224(sp)
    80000528:	f1f6                	sd	t4,224(sp)
        sd t5, 232(sp)
    8000052a:	f5fa                	sd	t5,232(sp)
        sd t6, 240(sp)
    8000052c:	f9fe                	sd	t6,240(sp)

        # 调用C语言的中断处理函数
        call kerneltrap
    8000052e:	f1dff0ef          	jal	8000044a <kerneltrap>

        # 恢复寄存器
        ld ra, 0(sp)
    80000532:	6082                	ld	ra,0(sp)
        ld gp, 16(sp)
    80000534:	61c2                	ld	gp,16(sp)
        # 不恢复tp（包含hartid），以防我们切换了CPU
        ld t0, 32(sp)
    80000536:	7282                	ld	t0,32(sp)
        ld t1, 40(sp)
    80000538:	7322                	ld	t1,40(sp)
        ld t2, 48(sp)
    8000053a:	73c2                	ld	t2,48(sp)
        ld s0, 56(sp)
    8000053c:	7462                	ld	s0,56(sp)
        ld s1, 64(sp)
    8000053e:	6486                	ld	s1,64(sp)
        ld a0, 72(sp)
    80000540:	6526                	ld	a0,72(sp)
        ld a1, 80(sp)
    80000542:	65c6                	ld	a1,80(sp)
        ld a2, 88(sp)
    80000544:	6666                	ld	a2,88(sp)
        ld a3, 96(sp)
    80000546:	7686                	ld	a3,96(sp)
        ld a4, 104(sp)
    80000548:	7726                	ld	a4,104(sp)
        ld a5, 112(sp)
    8000054a:	77c6                	ld	a5,112(sp)
        ld a6, 120(sp)
    8000054c:	7866                	ld	a6,120(sp)
        ld a7, 128(sp)
    8000054e:	688a                	ld	a7,128(sp)
        ld s2, 136(sp)
    80000550:	692a                	ld	s2,136(sp)
        ld s3, 144(sp)
    80000552:	69ca                	ld	s3,144(sp)
        ld s4, 152(sp)
    80000554:	6a6a                	ld	s4,152(sp)
        ld s5, 160(sp)
    80000556:	7a8a                	ld	s5,160(sp)
        ld s6, 168(sp)
    80000558:	7b2a                	ld	s6,168(sp)
        ld s7, 176(sp)
    8000055a:	7bca                	ld	s7,176(sp)
        ld s8, 184(sp)
    8000055c:	7c6a                	ld	s8,184(sp)
        ld s9, 192(sp)
    8000055e:	6c8e                	ld	s9,192(sp)
        ld s10, 200(sp)
    80000560:	6d2e                	ld	s10,200(sp)
        ld s11, 208(sp)
    80000562:	6dce                	ld	s11,208(sp)
        ld t3, 216(sp)
    80000564:	6e6e                	ld	t3,216(sp)
        ld t4, 224(sp)
    80000566:	7e8e                	ld	t4,224(sp)
        ld t5, 232(sp)
    80000568:	7f2e                	ld	t5,232(sp)
        ld t6, 240(sp)
    8000056a:	7fce                	ld	t6,240(sp)

        # 恢复栈指针
        addi sp, sp, 256
    8000056c:	6111                	add	sp,sp,256

        # 返回到被中断的代码
        sret
    8000056e:	10200073          	sret
    80000572:	0001                	nop
    80000574:	00000013          	nop
    80000578:	00000013          	nop
    8000057c:	00000013          	nop

0000000080000580 <timervec>:
        # start.c已经设置了机器模式的时钟中断委托
        # 这里只是一个占位符，实际的时钟中断会被委托到supervisor模式
        # 如果到达这里，说明委托没有正确设置
        
        # 保存寄存器
        csrrw a0, mscratch, a0
    80000580:	34051573          	csrrw	a0,mscratch,a0
        sd a1, 0(a0)
    80000584:	e10c                	sd	a1,0(a0)
        sd a2, 8(a0)
    80000586:	e510                	sd	a2,8(a0)
        sd a3, 16(a0)
    80000588:	e914                	sd	a3,16(a0)
        # 设置下次时钟中断
        # 这里应该调用SBI来设置时钟
        # 但在我们的实现中，时钟中断应该被委托到S模式
        
        # 触发supervisor模式的时钟中断
        li a1, 2
    8000058a:	4589                	li	a1,2
        csrw sip, a1
    8000058c:	14459073          	csrw	sip,a1
        
        # 恢复寄存器
        ld a3, 16(a0)
    80000590:	6914                	ld	a3,16(a0)
        ld a2, 8(a0)
    80000592:	6510                	ld	a2,8(a0)
        ld a1, 0(a0)
    80000594:	610c                	ld	a1,0(a0)
        csrrw a0, mscratch, a0
    80000596:	34051573          	csrrw	a0,mscratch,a0
        
    8000059a:	30200073          	mret

000000008000059e <test_interrupt_handler>:
int trap_tests_failed = 0;

// 测试用的中断处理函数
static int test_interrupt_called = 0;
static void test_interrupt_handler(void)
{
    8000059e:	1141                	add	sp,sp,-16
    800005a0:	e406                	sd	ra,8(sp)
    800005a2:	e022                	sd	s0,0(sp)
    800005a4:	0800                	add	s0,sp,16
    test_interrupt_called++;
    800005a6:	00006797          	auipc	a5,0x6
    800005aa:	b7678793          	add	a5,a5,-1162 # 8000611c <test_interrupt_called>
    800005ae:	438c                	lw	a1,0(a5)
    800005b0:	2585                	addw	a1,a1,1
    800005b2:	c38c                	sw	a1,0(a5)
    printf("  Test interrupt handler called (count: %d)\n", test_interrupt_called);
    800005b4:	2581                	sext.w	a1,a1
    800005b6:	00003517          	auipc	a0,0x3
    800005ba:	dea50513          	add	a0,a0,-534 # 800033a0 <etext+0x3a0>
    800005be:	1d7000ef          	jal	80000f94 <printf>
}
    800005c2:	60a2                	ld	ra,8(sp)
    800005c4:	6402                	ld	s0,0(sp)
    800005c6:	0141                	add	sp,sp,16
    800005c8:	8082                	ret

00000000800005ca <test_exception_handler>:

// 测试用的异常处理函数
static int test_exception_called = 0;
static void test_exception_handler(uint64 cause, uint64 epc, uint64 tval)
{
    800005ca:	1141                	add	sp,sp,-16
    800005cc:	e406                	sd	ra,8(sp)
    800005ce:	e022                	sd	s0,0(sp)
    800005d0:	0800                	add	s0,sp,16
    800005d2:	86b2                	mv	a3,a2
    test_exception_called++;
    800005d4:	00006717          	auipc	a4,0x6
    800005d8:	b4470713          	add	a4,a4,-1212 # 80006118 <test_exception_called>
    800005dc:	431c                	lw	a5,0(a4)
    800005de:	2785                	addw	a5,a5,1
    800005e0:	c31c                	sw	a5,0(a4)
    printf("  Test exception handler called: cause=0x%lx, epc=0x%lx, tval=0x%lx\n", 
    800005e2:	862e                	mv	a2,a1
    800005e4:	85aa                	mv	a1,a0
    800005e6:	00003517          	auipc	a0,0x3
    800005ea:	dea50513          	add	a0,a0,-534 # 800033d0 <etext+0x3d0>
    800005ee:	1a7000ef          	jal	80000f94 <printf>
           cause, epc, tval);
}
    800005f2:	60a2                	ld	ra,8(sp)
    800005f4:	6402                	ld	s0,0(sp)
    800005f6:	0141                	add	sp,sp,16
    800005f8:	8082                	ret

00000000800005fa <test_interrupt_system>:

/*
 * 测试中断系统基本功能
 */
void test_interrupt_system(void)
{
    800005fa:	1101                	add	sp,sp,-32
    800005fc:	ec06                	sd	ra,24(sp)
    800005fe:	e822                	sd	s0,16(sp)
    80000600:	e426                	sd	s1,8(sp)
    80000602:	1000                	add	s0,sp,32
    TRAP_TEST_START("Interrupt System");
    80000604:	00003597          	auipc	a1,0x3
    80000608:	e1458593          	add	a1,a1,-492 # 80003418 <etext+0x418>
    8000060c:	00003517          	auipc	a0,0x3
    80000610:	e2450513          	add	a0,a0,-476 # 80003430 <etext+0x430>
    80000614:	181000ef          	jal	80000f94 <printf>
    
    // 测试中断注册
    printf("  Testing interrupt registration...\n");
    80000618:	00003517          	auipc	a0,0x3
    8000061c:	e3050513          	add	a0,a0,-464 # 80003448 <etext+0x448>
    80000620:	175000ef          	jal	80000f94 <printf>
    register_interrupt(IRQ_S_TIMER, test_interrupt_handler);
    80000624:	00000597          	auipc	a1,0x0
    80000628:	f7a58593          	add	a1,a1,-134 # 8000059e <test_interrupt_handler>
    8000062c:	4515                	li	a0,5
    8000062e:	ad7ff0ef          	jal	80000104 <register_interrupt>
    TRAP_ASSERT(1, "Interrupt registration should succeed");
    80000632:	00006717          	auipc	a4,0x6
    80000636:	af270713          	add	a4,a4,-1294 # 80006124 <trap_tests_passed>
    8000063a:	431c                	lw	a5,0(a4)
    8000063c:	2785                	addw	a5,a5,1
    8000063e:	c31c                	sw	a5,0(a4)
    
    // 测试中断使能/禁用
    printf("  Testing interrupt enable/disable...\n");
    80000640:	00003517          	auipc	a0,0x3
    80000644:	e3050513          	add	a0,a0,-464 # 80003470 <etext+0x470>
    80000648:	14d000ef          	jal	80000f94 <printf>
    uint64 x = r_sstatus();
    8000064c:	100024f3          	csrr	s1,sstatus
    return (x & SSTATUS_SIE) != 0;
    80000650:	8889                	and	s1,s1,2
    w_sstatus(r_sstatus() & ~SSTATUS_SIE);
    80000652:	100027f3          	csrr	a5,sstatus
    80000656:	9bf5                	and	a5,a5,-3
    80000658:	10079073          	csrw	sstatus,a5
    uint64 x = r_sstatus();
    8000065c:	100027f3          	csrr	a5,sstatus
    return (x & SSTATUS_SIE) != 0;
    80000660:	8b89                	and	a5,a5,2
    
    int old_intr = intr_get();
    intr_off();
    TRAP_ASSERT(intr_get() == 0, "Interrupts should be disabled");
    80000662:	efc5                	bnez	a5,8000071a <test_interrupt_system+0x120>
    80000664:	00006717          	auipc	a4,0x6
    80000668:	ac070713          	add	a4,a4,-1344 # 80006124 <trap_tests_passed>
    8000066c:	431c                	lw	a5,0(a4)
    8000066e:	2785                	addw	a5,a5,1
    80000670:	c31c                	sw	a5,0(a4)
    w_sstatus(r_sstatus() | SSTATUS_SIE);
    80000672:	100027f3          	csrr	a5,sstatus
    80000676:	0027e793          	or	a5,a5,2
    8000067a:	10079073          	csrw	sstatus,a5
    uint64 x = r_sstatus();
    8000067e:	100027f3          	csrr	a5,sstatus
    return (x & SSTATUS_SIE) != 0;
    80000682:	8b89                	and	a5,a5,2
    
    intr_on();
    TRAP_ASSERT(intr_get() != 0, "Interrupts should be enabled");
    80000684:	cfcd                	beqz	a5,8000073e <test_interrupt_system+0x144>
    80000686:	00006717          	auipc	a4,0x6
    8000068a:	a9e70713          	add	a4,a4,-1378 # 80006124 <trap_tests_passed>
    8000068e:	431c                	lw	a5,0(a4)
    80000690:	2785                	addw	a5,a5,1
    80000692:	c31c                	sw	a5,0(a4)
    
    // 恢复原来的中断状态
    if (old_intr) {
    80000694:	c4f9                	beqz	s1,80000762 <test_interrupt_system+0x168>
    w_sstatus(r_sstatus() | SSTATUS_SIE);
    80000696:	100027f3          	csrr	a5,sstatus
    8000069a:	0027e793          	or	a5,a5,2
    8000069e:	10079073          	csrw	sstatus,a5
    } else {
        intr_off();
    }
    
    // 测试特定中断的使能/禁用
    printf("  Testing specific interrupt control...\n");
    800006a2:	00003517          	auipc	a0,0x3
    800006a6:	e5650513          	add	a0,a0,-426 # 800034f8 <etext+0x4f8>
    800006aa:	0eb000ef          	jal	80000f94 <printf>
    enable_interrupt(IRQ_S_TIMER);
    800006ae:	4515                	li	a0,5
    800006b0:	b2dff0ef          	jal	800001dc <enable_interrupt>
    uint64 sie = r_sie();
    800006b4:	104027f3          	csrr	a5,sie
    TRAP_ASSERT((sie & SIE_STIE) != 0, "Timer interrupt should be enabled");
    800006b8:	0207f793          	and	a5,a5,32
    800006bc:	cbcd                	beqz	a5,8000076e <test_interrupt_system+0x174>
    800006be:	00006717          	auipc	a4,0x6
    800006c2:	a6670713          	add	a4,a4,-1434 # 80006124 <trap_tests_passed>
    800006c6:	431c                	lw	a5,0(a4)
    800006c8:	2785                	addw	a5,a5,1
    800006ca:	c31c                	sw	a5,0(a4)
    
    disable_interrupt(IRQ_S_TIMER);
    800006cc:	4515                	li	a0,5
    800006ce:	b47ff0ef          	jal	80000214 <disable_interrupt>
    sie = r_sie();
    800006d2:	104027f3          	csrr	a5,sie
    TRAP_ASSERT((sie & SIE_STIE) == 0, "Timer interrupt should be disabled");
    800006d6:	0207f793          	and	a5,a5,32
    800006da:	efc5                	bnez	a5,80000792 <test_interrupt_system+0x198>
    800006dc:	00006717          	auipc	a4,0x6
    800006e0:	a4870713          	add	a4,a4,-1464 # 80006124 <trap_tests_passed>
    800006e4:	431c                	lw	a5,0(a4)
    800006e6:	2785                	addw	a5,a5,1
    800006e8:	c31c                	sw	a5,0(a4)
    
    // 重新启用时钟中断
    enable_interrupt(IRQ_S_TIMER);
    800006ea:	4515                	li	a0,5
    800006ec:	af1ff0ef          	jal	800001dc <enable_interrupt>
    
    printf("  Interrupt system tests passed\n");
    800006f0:	00003517          	auipc	a0,0x3
    800006f4:	e8850513          	add	a0,a0,-376 # 80003578 <etext+0x578>
    800006f8:	09d000ef          	jal	80000f94 <printf>
    TRAP_TEST_END("Interrupt System");
    800006fc:	00003597          	auipc	a1,0x3
    80000700:	d1c58593          	add	a1,a1,-740 # 80003418 <etext+0x418>
    80000704:	00003517          	auipc	a0,0x3
    80000708:	e9c50513          	add	a0,a0,-356 # 800035a0 <etext+0x5a0>
    8000070c:	089000ef          	jal	80000f94 <printf>
}
    80000710:	60e2                	ld	ra,24(sp)
    80000712:	6442                	ld	s0,16(sp)
    80000714:	64a2                	ld	s1,8(sp)
    80000716:	6105                	add	sp,sp,32
    80000718:	8082                	ret
    TRAP_ASSERT(intr_get() == 0, "Interrupts should be disabled");
    8000071a:	00003597          	auipc	a1,0x3
    8000071e:	d7e58593          	add	a1,a1,-642 # 80003498 <etext+0x498>
    80000722:	00003517          	auipc	a0,0x3
    80000726:	d9650513          	add	a0,a0,-618 # 800034b8 <etext+0x4b8>
    8000072a:	06b000ef          	jal	80000f94 <printf>
    8000072e:	00006717          	auipc	a4,0x6
    80000732:	9f270713          	add	a4,a4,-1550 # 80006120 <trap_tests_failed>
    80000736:	431c                	lw	a5,0(a4)
    80000738:	2785                	addw	a5,a5,1
    8000073a:	c31c                	sw	a5,0(a4)
    8000073c:	bf1d                	j	80000672 <test_interrupt_system+0x78>
    TRAP_ASSERT(intr_get() != 0, "Interrupts should be enabled");
    8000073e:	00003597          	auipc	a1,0x3
    80000742:	d9a58593          	add	a1,a1,-614 # 800034d8 <etext+0x4d8>
    80000746:	00003517          	auipc	a0,0x3
    8000074a:	d7250513          	add	a0,a0,-654 # 800034b8 <etext+0x4b8>
    8000074e:	047000ef          	jal	80000f94 <printf>
    80000752:	00006717          	auipc	a4,0x6
    80000756:	9ce70713          	add	a4,a4,-1586 # 80006120 <trap_tests_failed>
    8000075a:	431c                	lw	a5,0(a4)
    8000075c:	2785                	addw	a5,a5,1
    8000075e:	c31c                	sw	a5,0(a4)
    80000760:	bf15                	j	80000694 <test_interrupt_system+0x9a>
    w_sstatus(r_sstatus() & ~SSTATUS_SIE);
    80000762:	100027f3          	csrr	a5,sstatus
    80000766:	9bf5                	and	a5,a5,-3
    80000768:	10079073          	csrw	sstatus,a5
}
    8000076c:	bf1d                	j	800006a2 <test_interrupt_system+0xa8>
    TRAP_ASSERT((sie & SIE_STIE) != 0, "Timer interrupt should be enabled");
    8000076e:	00003597          	auipc	a1,0x3
    80000772:	dba58593          	add	a1,a1,-582 # 80003528 <etext+0x528>
    80000776:	00003517          	auipc	a0,0x3
    8000077a:	d4250513          	add	a0,a0,-702 # 800034b8 <etext+0x4b8>
    8000077e:	017000ef          	jal	80000f94 <printf>
    80000782:	00006717          	auipc	a4,0x6
    80000786:	99e70713          	add	a4,a4,-1634 # 80006120 <trap_tests_failed>
    8000078a:	431c                	lw	a5,0(a4)
    8000078c:	2785                	addw	a5,a5,1
    8000078e:	c31c                	sw	a5,0(a4)
    80000790:	bf35                	j	800006cc <test_interrupt_system+0xd2>
    TRAP_ASSERT((sie & SIE_STIE) == 0, "Timer interrupt should be disabled");
    80000792:	00003597          	auipc	a1,0x3
    80000796:	dbe58593          	add	a1,a1,-578 # 80003550 <etext+0x550>
    8000079a:	00003517          	auipc	a0,0x3
    8000079e:	d1e50513          	add	a0,a0,-738 # 800034b8 <etext+0x4b8>
    800007a2:	7f2000ef          	jal	80000f94 <printf>
    800007a6:	00006717          	auipc	a4,0x6
    800007aa:	97a70713          	add	a4,a4,-1670 # 80006120 <trap_tests_failed>
    800007ae:	431c                	lw	a5,0(a4)
    800007b0:	2785                	addw	a5,a5,1
    800007b2:	c31c                	sw	a5,0(a4)
    800007b4:	bf1d                	j	800006ea <test_interrupt_system+0xf0>

00000000800007b6 <test_timer_interrupt>:

/*
 * 测试时钟中断
 */
void test_timer_interrupt(void)
{
    800007b6:	1141                	add	sp,sp,-16
    800007b8:	e406                	sd	ra,8(sp)
    800007ba:	e022                	sd	s0,0(sp)
    800007bc:	0800                	add	s0,sp,16
    TRAP_TEST_START("Timer Interrupt");
    800007be:	00003597          	auipc	a1,0x3
    800007c2:	dfa58593          	add	a1,a1,-518 # 800035b8 <etext+0x5b8>
    800007c6:	00003517          	auipc	a0,0x3
    800007ca:	c6a50513          	add	a0,a0,-918 # 80003430 <etext+0x430>
    800007ce:	7c6000ef          	jal	80000f94 <printf>
    
    printf("  Testing timer interrupt...\n");
    800007d2:	00003517          	auipc	a0,0x3
    800007d6:	df650513          	add	a0,a0,-522 # 800035c8 <etext+0x5c8>
    800007da:	7ba000ef          	jal	80000f94 <printf>
    
    // 等待一些时钟中断
    printf("  Current ticks: %ld\n", ticks);
    800007de:	00006597          	auipc	a1,0x6
    800007e2:	9325b583          	ld	a1,-1742(a1) # 80006110 <ticks>
    800007e6:	00003517          	auipc	a0,0x3
    800007ea:	e0250513          	add	a0,a0,-510 # 800035e8 <etext+0x5e8>
    800007ee:	7a6000ef          	jal	80000f94 <printf>
    printf("  Note: Timer interrupts not fully implemented yet\n");
    800007f2:	00003517          	auipc	a0,0x3
    800007f6:	e0e50513          	add	a0,a0,-498 # 80003600 <etext+0x600>
    800007fa:	79a000ef          	jal	80000f94 <printf>
    
    // 简化测试，不实际等待时钟中断
    printf("  Timer interrupt framework ready\n");
    800007fe:	00003517          	auipc	a0,0x3
    80000802:	e3a50513          	add	a0,a0,-454 # 80003638 <etext+0x638>
    80000806:	78e000ef          	jal	80000f94 <printf>
    
    TRAP_ASSERT(1, "Timer interrupt framework should be ready");
    8000080a:	00006717          	auipc	a4,0x6
    8000080e:	91a70713          	add	a4,a4,-1766 # 80006124 <trap_tests_passed>
    80000812:	431c                	lw	a5,0(a4)
    80000814:	2785                	addw	a5,a5,1
    80000816:	c31c                	sw	a5,0(a4)
    
    printf("  Timer interrupt tests passed\n");
    80000818:	00003517          	auipc	a0,0x3
    8000081c:	e4850513          	add	a0,a0,-440 # 80003660 <etext+0x660>
    80000820:	774000ef          	jal	80000f94 <printf>
    TRAP_TEST_END("Timer Interrupt");
    80000824:	00003597          	auipc	a1,0x3
    80000828:	d9458593          	add	a1,a1,-620 # 800035b8 <etext+0x5b8>
    8000082c:	00003517          	auipc	a0,0x3
    80000830:	d7450513          	add	a0,a0,-652 # 800035a0 <etext+0x5a0>
    80000834:	760000ef          	jal	80000f94 <printf>
}
    80000838:	60a2                	ld	ra,8(sp)
    8000083a:	6402                	ld	s0,0(sp)
    8000083c:	0141                	add	sp,sp,16
    8000083e:	8082                	ret

0000000080000840 <test_exception_handling>:

/*
 * 测试异常处理
 */
void test_exception_handling(void)
{
    80000840:	1141                	add	sp,sp,-16
    80000842:	e406                	sd	ra,8(sp)
    80000844:	e022                	sd	s0,0(sp)
    80000846:	0800                	add	s0,sp,16
    TRAP_TEST_START("Exception Handling");
    80000848:	00003597          	auipc	a1,0x3
    8000084c:	e3858593          	add	a1,a1,-456 # 80003680 <etext+0x680>
    80000850:	00003517          	auipc	a0,0x3
    80000854:	be050513          	add	a0,a0,-1056 # 80003430 <etext+0x430>
    80000858:	73c000ef          	jal	80000f94 <printf>
    
    printf("  Testing exception handling...\n");
    8000085c:	00003517          	auipc	a0,0x3
    80000860:	e3c50513          	add	a0,a0,-452 # 80003698 <etext+0x698>
    80000864:	730000ef          	jal	80000f94 <printf>
    
    // 注册测试异常处理函数
    register_exception(CAUSE_BREAKPOINT, test_exception_handler);
    80000868:	00000597          	auipc	a1,0x0
    8000086c:	d6258593          	add	a1,a1,-670 # 800005ca <test_exception_handler>
    80000870:	450d                	li	a0,3
    80000872:	933ff0ef          	jal	800001a4 <register_exception>
    
    // 测试断点异常（ebreak指令）
    printf("  Testing breakpoint exception...\n");
    80000876:	00003517          	auipc	a0,0x3
    8000087a:	e4a50513          	add	a0,a0,-438 # 800036c0 <etext+0x6c0>
    8000087e:	716000ef          	jal	80000f94 <printf>
    test_exception_called = 0;
    80000882:	00006797          	auipc	a5,0x6
    80000886:	8807ab23          	sw	zero,-1898(a5) # 80006118 <test_exception_called>
    
    // 注意：这里不实际触发异常，因为可能导致系统不稳定
    // 在实际系统中，可以通过ebreak指令触发断点异常
    // asm volatile("ebreak");
    
    printf("  Exception handling framework ready\n");
    8000088a:	00003517          	auipc	a0,0x3
    8000088e:	e5e50513          	add	a0,a0,-418 # 800036e8 <etext+0x6e8>
    80000892:	702000ef          	jal	80000f94 <printf>
    TRAP_ASSERT(1, "Exception handling framework should be ready");
    80000896:	00006717          	auipc	a4,0x6
    8000089a:	88e70713          	add	a4,a4,-1906 # 80006124 <trap_tests_passed>
    8000089e:	431c                	lw	a5,0(a4)
    800008a0:	2785                	addw	a5,a5,1
    800008a2:	c31c                	sw	a5,0(a4)
    
    printf("  Exception handling tests passed\n");
    800008a4:	00003517          	auipc	a0,0x3
    800008a8:	e6c50513          	add	a0,a0,-404 # 80003710 <etext+0x710>
    800008ac:	6e8000ef          	jal	80000f94 <printf>
    TRAP_TEST_END("Exception Handling");
    800008b0:	00003597          	auipc	a1,0x3
    800008b4:	dd058593          	add	a1,a1,-560 # 80003680 <etext+0x680>
    800008b8:	00003517          	auipc	a0,0x3
    800008bc:	ce850513          	add	a0,a0,-792 # 800035a0 <etext+0x5a0>
    800008c0:	6d4000ef          	jal	80000f94 <printf>
}
    800008c4:	60a2                	ld	ra,8(sp)
    800008c6:	6402                	ld	s0,0(sp)
    800008c8:	0141                	add	sp,sp,16
    800008ca:	8082                	ret

00000000800008cc <test_interrupt_overhead>:

/*
 * 测试中断开销
 */
void test_interrupt_overhead(void)
{
    800008cc:	1141                	add	sp,sp,-16
    800008ce:	e406                	sd	ra,8(sp)
    800008d0:	e022                	sd	s0,0(sp)
    800008d2:	0800                	add	s0,sp,16
    TRAP_TEST_START("Interrupt Overhead");
    800008d4:	00003597          	auipc	a1,0x3
    800008d8:	e6458593          	add	a1,a1,-412 # 80003738 <etext+0x738>
    800008dc:	00003517          	auipc	a0,0x3
    800008e0:	b5450513          	add	a0,a0,-1196 # 80003430 <etext+0x430>
    800008e4:	6b0000ef          	jal	80000f94 <printf>
    
    printf("  Testing interrupt overhead...\n");
    800008e8:	00003517          	auipc	a0,0x3
    800008ec:	e6850513          	add	a0,a0,-408 # 80003750 <etext+0x750>
    800008f0:	6a4000ef          	jal	80000f94 <printf>
    
    // 简化测试，不实际测量时钟
    printf("  Note: Detailed timing measurements not available\n");
    800008f4:	00003517          	auipc	a0,0x3
    800008f8:	e8450513          	add	a0,a0,-380 # 80003778 <etext+0x778>
    800008fc:	698000ef          	jal	80000f94 <printf>
    printf("  Interrupt overhead framework ready\n");
    80000900:	00003517          	auipc	a0,0x3
    80000904:	eb050513          	add	a0,a0,-336 # 800037b0 <etext+0x7b0>
    80000908:	68c000ef          	jal	80000f94 <printf>
    
    TRAP_ASSERT(1, "Interrupt overhead framework should be ready");
    8000090c:	00006717          	auipc	a4,0x6
    80000910:	81870713          	add	a4,a4,-2024 # 80006124 <trap_tests_passed>
    80000914:	431c                	lw	a5,0(a4)
    80000916:	2785                	addw	a5,a5,1
    80000918:	c31c                	sw	a5,0(a4)
    
    printf("  Interrupt overhead tests passed\n");
    8000091a:	00003517          	auipc	a0,0x3
    8000091e:	ebe50513          	add	a0,a0,-322 # 800037d8 <etext+0x7d8>
    80000922:	672000ef          	jal	80000f94 <printf>
    TRAP_TEST_END("Interrupt Overhead");
    80000926:	00003597          	auipc	a1,0x3
    8000092a:	e1258593          	add	a1,a1,-494 # 80003738 <etext+0x738>
    8000092e:	00003517          	auipc	a0,0x3
    80000932:	c7250513          	add	a0,a0,-910 # 800035a0 <etext+0x5a0>
    80000936:	65e000ef          	jal	80000f94 <printf>
}
    8000093a:	60a2                	ld	ra,8(sp)
    8000093c:	6402                	ld	s0,0(sp)
    8000093e:	0141                	add	sp,sp,16
    80000940:	8082                	ret

0000000080000942 <run_all_trap_tests>:

/*
 * 运行所有中断处理测试
 */
void run_all_trap_tests(void)
{
    80000942:	1101                	add	sp,sp,-32
    80000944:	ec06                	sd	ra,24(sp)
    80000946:	e822                	sd	s0,16(sp)
    80000948:	e426                	sd	s1,8(sp)
    8000094a:	e04a                	sd	s2,0(sp)
    8000094c:	1000                	add	s0,sp,32
    printf("\n=== Trap and Interrupt Tests ===\n");
    8000094e:	00003517          	auipc	a0,0x3
    80000952:	eb250513          	add	a0,a0,-334 # 80003800 <etext+0x800>
    80000956:	63e000ef          	jal	80000f94 <printf>
    
    trap_tests_passed = 0;
    8000095a:	00005917          	auipc	s2,0x5
    8000095e:	7ca90913          	add	s2,s2,1994 # 80006124 <trap_tests_passed>
    80000962:	00092023          	sw	zero,0(s2)
    trap_tests_failed = 0;
    80000966:	00005497          	auipc	s1,0x5
    8000096a:	7ba48493          	add	s1,s1,1978 # 80006120 <trap_tests_failed>
    8000096e:	0004a023          	sw	zero,0(s1)
    
    // 运行测试
    test_interrupt_system();
    80000972:	c89ff0ef          	jal	800005fa <test_interrupt_system>
    test_timer_interrupt();
    80000976:	e41ff0ef          	jal	800007b6 <test_timer_interrupt>
    test_exception_handling();
    8000097a:	ec7ff0ef          	jal	80000840 <test_exception_handling>
    test_interrupt_overhead();
    8000097e:	f4fff0ef          	jal	800008cc <test_interrupt_overhead>
    
    // 输出测试结果
    printf("\n=== Trap Test Results ===\n");
    80000982:	00003517          	auipc	a0,0x3
    80000986:	ea650513          	add	a0,a0,-346 # 80003828 <etext+0x828>
    8000098a:	60a000ef          	jal	80000f94 <printf>
    printf("Tests passed: %d\n", trap_tests_passed);
    8000098e:	00092583          	lw	a1,0(s2)
    80000992:	00003517          	auipc	a0,0x3
    80000996:	eb650513          	add	a0,a0,-330 # 80003848 <etext+0x848>
    8000099a:	5fa000ef          	jal	80000f94 <printf>
    printf("Tests failed: %d\n", trap_tests_failed);
    8000099e:	408c                	lw	a1,0(s1)
    800009a0:	00003517          	auipc	a0,0x3
    800009a4:	ec050513          	add	a0,a0,-320 # 80003860 <etext+0x860>
    800009a8:	5ec000ef          	jal	80000f94 <printf>
    
    if (trap_tests_failed == 0) {
    800009ac:	409c                	lw	a5,0(s1)
    800009ae:	e39d                	bnez	a5,800009d4 <run_all_trap_tests+0x92>
        printf("All trap tests PASSED!\n");
    800009b0:	00003517          	auipc	a0,0x3
    800009b4:	ec850513          	add	a0,a0,-312 # 80003878 <etext+0x878>
    800009b8:	5dc000ef          	jal	80000f94 <printf>
    } else {
        printf("Some trap tests FAILED!\n");
    }
    
    printf("=== End of Trap Tests ===\n\n");
    800009bc:	00003517          	auipc	a0,0x3
    800009c0:	ef450513          	add	a0,a0,-268 # 800038b0 <etext+0x8b0>
    800009c4:	5d0000ef          	jal	80000f94 <printf>
    800009c8:	60e2                	ld	ra,24(sp)
    800009ca:	6442                	ld	s0,16(sp)
    800009cc:	64a2                	ld	s1,8(sp)
    800009ce:	6902                	ld	s2,0(sp)
    800009d0:	6105                	add	sp,sp,32
    800009d2:	8082                	ret
        printf("Some trap tests FAILED!\n");
    800009d4:	00003517          	auipc	a0,0x3
    800009d8:	ebc50513          	add	a0,a0,-324 # 80003890 <etext+0x890>
    800009dc:	5b8000ef          	jal	80000f94 <printf>
    800009e0:	bff1                	j	800009bc <run_all_trap_tests+0x7a>

00000000800009e2 <main>:
#include "../mm/mm_test.h"
#include "../trap/trap.h"
#include "../trap/trap_test.h"

// 内核主函数（汇编中call跳转至此）
void main() {
    800009e2:	1101                	add	sp,sp,-32
    800009e4:	ec06                	sd	ra,24(sp)
    800009e6:	e822                	sd	s0,16(sp)
    800009e8:	1000                	add	s0,sp,32
    // while (1) {
    //     // 待添加相关处理
    // }

    // 初始化UART串口
    uart_init();
    800009ea:	334000ef          	jal	80000d1e <uart_init>
    
    // 初始化printf系统
    printf_init();
    800009ee:	6ea000ef          	jal	800010d8 <printf_init>
    
    // 初始化内存管理系统
    printf("Initializing memory management...\n");
    800009f2:	00003517          	auipc	a0,0x3
    800009f6:	ede50513          	add	a0,a0,-290 # 800038d0 <etext+0x8d0>
    800009fa:	59a000ef          	jal	80000f94 <printf>
    pmm_init();  // 初始化物理内存分配器
    800009fe:	052010ef          	jal	80001a50 <pmm_init>
    printf("Physical memory allocator initialized\n");
    80000a02:	00003517          	auipc	a0,0x3
    80000a06:	ef650513          	add	a0,a0,-266 # 800038f8 <etext+0x8f8>
    80000a0a:	58a000ef          	jal	80000f94 <printf>

    // 初始化中断处理系统
    printf("Initializing trap system...\n");
    80000a0e:	00002517          	auipc	a0,0x2
    80000a12:	65250513          	add	a0,a0,1618 # 80003060 <etext+0x60>
    80000a16:	57e000ef          	jal	80000f94 <printf>
    trap_init();        // 初始化中断框架
    80000a1a:	f20ff0ef          	jal	8000013a <trap_init>
    trap_init_hart();   // 初始化当前hart的中断
    80000a1e:	ea6ff0ef          	jal	800000c4 <trap_init_hart>
    timer_init();       // 初始化时钟
    80000a22:	89bff0ef          	jal	800002bc <timer_init>
    printf("Trap system initialized\n");
    80000a26:	00003517          	auipc	a0,0x3
    80000a2a:	efa50513          	add	a0,a0,-262 # 80003920 <etext+0x920>
    80000a2e:	566000ef          	jal	80000f94 <printf>
    
    // 输出启动信息
    printf("\n");
    80000a32:	00003517          	auipc	a0,0x3
    80000a36:	25650513          	add	a0,a0,598 # 80003c88 <etext+0xc88>
    80000a3a:	55a000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000a3e:	00003517          	auipc	a0,0x3
    80000a42:	f0250513          	add	a0,a0,-254 # 80003940 <etext+0x940>
    80000a46:	54e000ef          	jal	80000f94 <printf>
    printf("    RISC-V Operating System v1.0       \n");
    80000a4a:	00003517          	auipc	a0,0x3
    80000a4e:	f2650513          	add	a0,a0,-218 # 80003970 <etext+0x970>
    80000a52:	542000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000a56:	00003517          	auipc	a0,0x3
    80000a5a:	eea50513          	add	a0,a0,-278 # 80003940 <etext+0x940>
    80000a5e:	536000ef          	jal	80000f94 <printf>
    printf("Hello OS!\n");
    80000a62:	00003517          	auipc	a0,0x3
    80000a66:	f3e50513          	add	a0,a0,-194 # 800039a0 <etext+0x9a0>
    80000a6a:	52a000ef          	jal	80000f94 <printf>
    printf("RISC-V Minimal Operating System Started.\n");
    80000a6e:	00003517          	auipc	a0,0x3
    80000a72:	f4250513          	add	a0,a0,-190 # 800039b0 <etext+0x9b0>
    80000a76:	51e000ef          	jal	80000f94 <printf>
    printf("This is a kernel with printf support.\n");
    80000a7a:	00003517          	auipc	a0,0x3
    80000a7e:	f6650513          	add	a0,a0,-154 # 800039e0 <etext+0x9e0>
    80000a82:	512000ef          	jal	80000f94 <printf>
    printf("\n");
    80000a86:	00003517          	auipc	a0,0x3
    80000a8a:	20250513          	add	a0,a0,514 # 80003c88 <etext+0xc88>
    80000a8e:	506000ef          	jal	80000f94 <printf>
    
    // 显示系统信息（使用printf格式化）
    printf("System Information:\n");
    80000a92:	00003517          	auipc	a0,0x3
    80000a96:	f7650513          	add	a0,a0,-138 # 80003a08 <etext+0xa08>
    80000a9a:	4fa000ef          	jal	80000f94 <printf>
    printf("- Kernel loaded at: 0x%lx\n", 0x80000000UL);
    80000a9e:	4585                	li	a1,1
    80000aa0:	05fe                	sll	a1,a1,0x1f
    80000aa2:	00003517          	auipc	a0,0x3
    80000aa6:	f7e50513          	add	a0,a0,-130 # 80003a20 <etext+0xa20>
    80000aaa:	4ea000ef          	jal	80000f94 <printf>
    printf("- Stack pointer at: 0x%lx\n", 0x80010000UL);
    80000aae:	080015b7          	lui	a1,0x8001
    80000ab2:	0592                	sll	a1,a1,0x4
    80000ab4:	00003517          	auipc	a0,0x3
    80000ab8:	f8c50513          	add	a0,a0,-116 # 80003a40 <etext+0xa40>
    80000abc:	4d8000ef          	jal	80000f94 <printf>
    printf("- Printf system: %s\n", "Initialized");
    80000ac0:	00003597          	auipc	a1,0x3
    80000ac4:	fa058593          	add	a1,a1,-96 # 80003a60 <etext+0xa60>
    80000ac8:	00003517          	auipc	a0,0x3
    80000acc:	fa850513          	add	a0,a0,-88 # 80003a70 <etext+0xa70>
    80000ad0:	4c4000ef          	jal	80000f94 <printf>
    printf("- Console features: %s\n", "Enabled");
    80000ad4:	00003597          	auipc	a1,0x3
    80000ad8:	fb458593          	add	a1,a1,-76 # 80003a88 <etext+0xa88>
    80000adc:	00003517          	auipc	a0,0x3
    80000ae0:	fb450513          	add	a0,a0,-76 # 80003a90 <etext+0xa90>
    80000ae4:	4b0000ef          	jal	80000f94 <printf>
    printf("\n");
    80000ae8:	00003517          	auipc	a0,0x3
    80000aec:	1a050513          	add	a0,a0,416 # 80003c88 <etext+0xc88>
    80000af0:	4a4000ef          	jal	80000f94 <printf>
    
    // 基本printf功能演示
    printf("Basic Printf Demo:\n");
    80000af4:	00003517          	auipc	a0,0x3
    80000af8:	fb450513          	add	a0,a0,-76 # 80003aa8 <etext+0xaa8>
    80000afc:	498000ef          	jal	80000f94 <printf>
    printf("- Integer: %d\n", 42);
    80000b00:	02a00593          	li	a1,42
    80000b04:	00003517          	auipc	a0,0x3
    80000b08:	fbc50513          	add	a0,a0,-68 # 80003ac0 <etext+0xac0>
    80000b0c:	488000ef          	jal	80000f94 <printf>
    printf("- Negative: %d\n", -123);
    80000b10:	f8500593          	li	a1,-123
    80000b14:	00003517          	auipc	a0,0x3
    80000b18:	fbc50513          	add	a0,a0,-68 # 80003ad0 <etext+0xad0>
    80000b1c:	478000ef          	jal	80000f94 <printf>
    printf("- Hex: 0x%x\n", 0xDEAD);
    80000b20:	65b9                	lui	a1,0xe
    80000b22:	ead58593          	add	a1,a1,-339 # dead <_entry-0x7fff2153>
    80000b26:	00003517          	auipc	a0,0x3
    80000b2a:	fba50513          	add	a0,a0,-70 # 80003ae0 <etext+0xae0>
    80000b2e:	466000ef          	jal	80000f94 <printf>
    printf("- Character: %c\n", 'A');
    80000b32:	04100593          	li	a1,65
    80000b36:	00003517          	auipc	a0,0x3
    80000b3a:	fba50513          	add	a0,a0,-70 # 80003af0 <etext+0xaf0>
    80000b3e:	456000ef          	jal	80000f94 <printf>
    printf("- String: %s\n", "Hello, Printf!");
    80000b42:	00003597          	auipc	a1,0x3
    80000b46:	fc658593          	add	a1,a1,-58 # 80003b08 <etext+0xb08>
    80000b4a:	00003517          	auipc	a0,0x3
    80000b4e:	fce50513          	add	a0,a0,-50 # 80003b18 <etext+0xb18>
    80000b52:	442000ef          	jal	80000f94 <printf>
    printf("- Pointer: %p\n", main);
    80000b56:	00000597          	auipc	a1,0x0
    80000b5a:	e8c58593          	add	a1,a1,-372 # 800009e2 <main>
    80000b5e:	00003517          	auipc	a0,0x3
    80000b62:	fca50513          	add	a0,a0,-54 # 80003b28 <etext+0xb28>
    80000b66:	42e000ef          	jal	80000f94 <printf>
    printf("\n");
    80000b6a:	00003517          	auipc	a0,0x3
    80000b6e:	11e50513          	add	a0,a0,286 # 80003c88 <etext+0xc88>
    80000b72:	422000ef          	jal	80000f94 <printf>
    
    // 清屏功能演示
    printf("========================================\n");
    80000b76:	00003517          	auipc	a0,0x3
    80000b7a:	dca50513          	add	a0,a0,-566 # 80003940 <etext+0x940>
    80000b7e:	416000ef          	jal	80000f94 <printf>
    printf("      Clear Screen Demo Starting       \n");
    80000b82:	00003517          	auipc	a0,0x3
    80000b86:	fb650513          	add	a0,a0,-74 # 80003b38 <etext+0xb38>
    80000b8a:	40a000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000b8e:	00003517          	auipc	a0,0x3
    80000b92:	db250513          	add	a0,a0,-590 # 80003940 <etext+0x940>
    80000b96:	3fe000ef          	jal	80000f94 <printf>
    printf("\n");
    80000b9a:	00003517          	auipc	a0,0x3
    80000b9e:	0ee50513          	add	a0,a0,238 # 80003c88 <etext+0xc88>
    80000ba2:	3f2000ef          	jal	80000f94 <printf>
    printf("This is the content BEFORE clearing...\n");
    80000ba6:	00003517          	auipc	a0,0x3
    80000baa:	fc250513          	add	a0,a0,-62 # 80003b68 <etext+0xb68>
    80000bae:	3e6000ef          	jal	80000f94 <printf>
    printf("Line 1: Hello World!\n");
    80000bb2:	00003517          	auipc	a0,0x3
    80000bb6:	fde50513          	add	a0,a0,-34 # 80003b90 <etext+0xb90>
    80000bba:	3da000ef          	jal	80000f94 <printf>
    printf("Line 2: Testing clear screen function\n");
    80000bbe:	00003517          	auipc	a0,0x3
    80000bc2:	fea50513          	add	a0,a0,-22 # 80003ba8 <etext+0xba8>
    80000bc6:	3ce000ef          	jal	80000f94 <printf>
    printf("Line 3: You should see this content now\n");
    80000bca:	00003517          	auipc	a0,0x3
    80000bce:	00650513          	add	a0,a0,6 # 80003bd0 <etext+0xbd0>
    80000bd2:	3c2000ef          	jal	80000f94 <printf>
    printf("Line 4: In 3 seconds, screen will be cleared\n");
    80000bd6:	00003517          	auipc	a0,0x3
    80000bda:	02a50513          	add	a0,a0,42 # 80003c00 <etext+0xc00>
    80000bde:	3b6000ef          	jal	80000f94 <printf>
    printf("\n");
    80000be2:	00003517          	auipc	a0,0x3
    80000be6:	0a650513          	add	a0,a0,166 # 80003c88 <etext+0xc88>
    80000bea:	3aa000ef          	jal	80000f94 <printf>
    printf("Waiting 3 seconds...\n");
    80000bee:	00003517          	auipc	a0,0x3
    80000bf2:	04250513          	add	a0,a0,66 # 80003c30 <etext+0xc30>
    80000bf6:	39e000ef          	jal	80000f94 <printf>
    
    // 延时模拟
    for (volatile int i = 0; i < 1000000000; i++) {
    80000bfa:	fe042623          	sw	zero,-20(s0)
    80000bfe:	fec42703          	lw	a4,-20(s0)
    80000c02:	2701                	sext.w	a4,a4
    80000c04:	3b9ad7b7          	lui	a5,0x3b9ad
    80000c08:	9ff78793          	add	a5,a5,-1537 # 3b9ac9ff <_entry-0x44653601>
    80000c0c:	00e7cd63          	blt	a5,a4,80000c26 <main+0x244>
    80000c10:	873e                	mv	a4,a5
    80000c12:	fec42783          	lw	a5,-20(s0)
    80000c16:	2785                	addw	a5,a5,1
    80000c18:	fef42623          	sw	a5,-20(s0)
    80000c1c:	fec42783          	lw	a5,-20(s0)
    80000c20:	2781                	sext.w	a5,a5
    80000c22:	fef758e3          	bge	a4,a5,80000c12 <main+0x230>
        // 延时循环
    }
    
    printf("Clearing screen NOW!\n");
    80000c26:	00003517          	auipc	a0,0x3
    80000c2a:	02250513          	add	a0,a0,34 # 80003c48 <etext+0xc48>
    80000c2e:	366000ef          	jal	80000f94 <printf>
    
    // 执行清屏
    clear_screen();
    80000c32:	174000ef          	jal	80000da6 <clear_screen>
    
    run_printf_tests();
    80000c36:	103000ef          	jal	80001538 <run_printf_tests>
    
    // 运行内存管理测试
    printf("\n");
    80000c3a:	00003517          	auipc	a0,0x3
    80000c3e:	04e50513          	add	a0,a0,78 # 80003c88 <etext+0xc88>
    80000c42:	352000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000c46:	00003517          	auipc	a0,0x3
    80000c4a:	cfa50513          	add	a0,a0,-774 # 80003940 <etext+0x940>
    80000c4e:	346000ef          	jal	80000f94 <printf>
    printf("    Running Memory Management Tests     \n");
    80000c52:	00003517          	auipc	a0,0x3
    80000c56:	00e50513          	add	a0,a0,14 # 80003c60 <etext+0xc60>
    80000c5a:	33a000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000c5e:	00003517          	auipc	a0,0x3
    80000c62:	ce250513          	add	a0,a0,-798 # 80003940 <etext+0x940>
    80000c66:	32e000ef          	jal	80000f94 <printf>
    run_all_mm_tests();
    80000c6a:	483010ef          	jal	800028ec <run_all_mm_tests>
    // printf("      Demo Clear Screen Function       \n");
    // printf("========================================\n");
    // demo_clear_screen();

    // 运行中断处理测试
    printf("\n");
    80000c6e:	00003517          	auipc	a0,0x3
    80000c72:	01a50513          	add	a0,a0,26 # 80003c88 <etext+0xc88>
    80000c76:	31e000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000c7a:	00003517          	auipc	a0,0x3
    80000c7e:	cc650513          	add	a0,a0,-826 # 80003940 <etext+0x940>
    80000c82:	312000ef          	jal	80000f94 <printf>
    printf("    Running Trap and Interrupt Tests    \n");
    80000c86:	00003517          	auipc	a0,0x3
    80000c8a:	00a50513          	add	a0,a0,10 # 80003c90 <etext+0xc90>
    80000c8e:	306000ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80000c92:	00003517          	auipc	a0,0x3
    80000c96:	cae50513          	add	a0,a0,-850 # 80003940 <etext+0x940>
    80000c9a:	2fa000ef          	jal	80000f94 <printf>
    run_all_trap_tests();
    80000c9e:	ca5ff0ef          	jal	80000942 <run_all_trap_tests>
    
    // 系统就绪提示
    printf("Available functions for testing:\n");
    80000ca2:	00003517          	auipc	a0,0x3
    80000ca6:	01e50513          	add	a0,a0,30 # 80003cc0 <etext+0xcc0>
    80000caa:	2ea000ef          	jal	80000f94 <printf>
    printf("- printf() with various formats\n");
    80000cae:	00003517          	auipc	a0,0x3
    80000cb2:	03a50513          	add	a0,a0,58 # 80003ce8 <etext+0xce8>
    80000cb6:	2de000ef          	jal	80000f94 <printf>
    printf("- console_clear() for screen clearing\n");
    80000cba:	00003517          	auipc	a0,0x3
    80000cbe:	05650513          	add	a0,a0,86 # 80003d10 <etext+0xd10>
    80000cc2:	2d2000ef          	jal	80000f94 <printf>
    printf("- console_set_color() for colors\n");
    80000cc6:	00003517          	auipc	a0,0x3
    80000cca:	07250513          	add	a0,a0,114 # 80003d38 <etext+0xd38>
    80000cce:	2c6000ef          	jal	80000f94 <printf>
    printf("- run_printf_tests() for full test suite\n");
    80000cd2:	00003517          	auipc	a0,0x3
    80000cd6:	08e50513          	add	a0,a0,142 # 80003d60 <etext+0xd60>
    80000cda:	2ba000ef          	jal	80000f94 <printf>
    printf("\n");
    80000cde:	00003517          	auipc	a0,0x3
    80000ce2:	faa50513          	add	a0,a0,-86 # 80003c88 <etext+0xc88>
    80000ce6:	2ae000ef          	jal	80000f94 <printf>
    printf("System ready for use!\n");
    80000cea:	00003517          	auipc	a0,0x3
    80000cee:	0a650513          	add	a0,a0,166 # 80003d90 <etext+0xd90>
    80000cf2:	2a2000ef          	jal	80000f94 <printf>
    
    // 系统主循环（防止退出）
    printf("Entering main loop...\n");
    80000cf6:	00003517          	auipc	a0,0x3
    80000cfa:	0b250513          	add	a0,a0,178 # 80003da8 <etext+0xda8>
    80000cfe:	296000ef          	jal	80000f94 <printf>
    while (1) {
    80000d02:	a001                	j	80000d02 <main+0x320>

0000000080000d04 <uart_wait_ready>:
    // 我们只需要确保能够发送数据
    // 实际硬件可能需要设置波特率等参数
}

// 等待UART发送就绪
static void uart_wait_ready() {
    80000d04:	1141                	add	sp,sp,-16
    80000d06:	e422                	sd	s0,8(sp)
    80000d08:	0800                	add	s0,sp,16
    // 循环检查THRE位，直到发送寄存器空闲
    while ((*(volatile unsigned char *)UART_LSR & LSR_TX_EMPTY) == 0);
    80000d0a:	10000737          	lui	a4,0x10000
    80000d0e:	00574783          	lbu	a5,5(a4) # 10000005 <_entry-0x6ffffffb>
    80000d12:	0207f793          	and	a5,a5,32
    80000d16:	dfe5                	beqz	a5,80000d0e <uart_wait_ready+0xa>
}
    80000d18:	6422                	ld	s0,8(sp)
    80000d1a:	0141                	add	sp,sp,16
    80000d1c:	8082                	ret

0000000080000d1e <uart_init>:
{
    80000d1e:	1141                	add	sp,sp,-16
    80000d20:	e422                	sd	s0,8(sp)
    80000d22:	0800                	add	s0,sp,16
}
    80000d24:	6422                	ld	s0,8(sp)
    80000d26:	0141                	add	sp,sp,16
    80000d28:	8082                	ret

0000000080000d2a <uart_putc>:

// 输出单个字符
void uart_putc(char c) {
    80000d2a:	1101                	add	sp,sp,-32
    80000d2c:	ec06                	sd	ra,24(sp)
    80000d2e:	e822                	sd	s0,16(sp)
    80000d30:	e426                	sd	s1,8(sp)
    80000d32:	1000                	add	s0,sp,32
    80000d34:	84aa                	mv	s1,a0
    uart_wait_ready();
    80000d36:	fcfff0ef          	jal	80000d04 <uart_wait_ready>
    // 写入发送寄存器（硬件自动发送）
    *(volatile unsigned char *)UART_THR = c;
    80000d3a:	100007b7          	lui	a5,0x10000
    80000d3e:	00978023          	sb	s1,0(a5) # 10000000 <_entry-0x70000000>
}
    80000d42:	60e2                	ld	ra,24(sp)
    80000d44:	6442                	ld	s0,16(sp)
    80000d46:	64a2                	ld	s1,8(sp)
    80000d48:	6105                	add	sp,sp,32
    80000d4a:	8082                	ret

0000000080000d4c <uart_puts>:

// 输出字符串（自动处理换行符）
void uart_puts(char *s) {
    for (int i = 0; s[i] != '\0'; i++) {
    80000d4c:	00054783          	lbu	a5,0(a0)
    80000d50:	cbb1                	beqz	a5,80000da4 <uart_puts+0x58>
void uart_puts(char *s) {
    80000d52:	7139                	add	sp,sp,-64
    80000d54:	fc06                	sd	ra,56(sp)
    80000d56:	f822                	sd	s0,48(sp)
    80000d58:	f426                	sd	s1,40(sp)
    80000d5a:	f04a                	sd	s2,32(sp)
    80000d5c:	ec4e                	sd	s3,24(sp)
    80000d5e:	e852                	sd	s4,16(sp)
    80000d60:	e456                	sd	s5,8(sp)
    80000d62:	0080                	add	s0,sp,64
    80000d64:	84aa                	mv	s1,a0
        // 对换行符补充回车（终端显示需要）
        if (s[i] == '\n') {
    80000d66:	4a29                	li	s4,10
    *(volatile unsigned char *)UART_THR = c;
    80000d68:	100009b7          	lui	s3,0x10000
    80000d6c:	4ab5                	li	s5,13
    80000d6e:	a819                	j	80000d84 <uart_puts+0x38>
            uart_putc('\r');
        }
        uart_putc(s[i]);
    80000d70:	0004c903          	lbu	s2,0(s1)
    uart_wait_ready();
    80000d74:	f91ff0ef          	jal	80000d04 <uart_wait_ready>
    *(volatile unsigned char *)UART_THR = c;
    80000d78:	01298023          	sb	s2,0(s3) # 10000000 <_entry-0x70000000>
    for (int i = 0; s[i] != '\0'; i++) {
    80000d7c:	0485                	add	s1,s1,1
    80000d7e:	0004c783          	lbu	a5,0(s1)
    80000d82:	cb81                	beqz	a5,80000d92 <uart_puts+0x46>
        if (s[i] == '\n') {
    80000d84:	ff4796e3          	bne	a5,s4,80000d70 <uart_puts+0x24>
    uart_wait_ready();
    80000d88:	f7dff0ef          	jal	80000d04 <uart_wait_ready>
    *(volatile unsigned char *)UART_THR = c;
    80000d8c:	01598023          	sb	s5,0(s3)
}
    80000d90:	b7c5                	j	80000d70 <uart_puts+0x24>
    }
}
    80000d92:	70e2                	ld	ra,56(sp)
    80000d94:	7442                	ld	s0,48(sp)
    80000d96:	74a2                	ld	s1,40(sp)
    80000d98:	7902                	ld	s2,32(sp)
    80000d9a:	69e2                	ld	s3,24(sp)
    80000d9c:	6a42                	ld	s4,16(sp)
    80000d9e:	6aa2                	ld	s5,8(sp)
    80000da0:	6121                	add	sp,sp,64
    80000da2:	8082                	ret
    80000da4:	8082                	ret

0000000080000da6 <clear_screen>:
#include "ansi_escapes.h"
#include "printf.h"

// 清屏并将光标移动到左上角
void clear_screen(void) {
    80000da6:	1141                	add	sp,sp,-16
    80000da8:	e406                	sd	ra,8(sp)
    80000daa:	e022                	sd	s0,0(sp)
    80000dac:	0800                	add	s0,sp,16
    printf(CLEAR_SCREEN);
    80000dae:	00003517          	auipc	a0,0x3
    80000db2:	01250513          	add	a0,a0,18 # 80003dc0 <etext+0xdc0>
    80000db6:	1de000ef          	jal	80000f94 <printf>
}
    80000dba:	60a2                	ld	ra,8(sp)
    80000dbc:	6402                	ld	s0,0(sp)
    80000dbe:	0141                	add	sp,sp,16
    80000dc0:	8082                	ret

0000000080000dc2 <clear_line>:

// 清除整行
void clear_line(void) {
    80000dc2:	1141                	add	sp,sp,-16
    80000dc4:	e406                	sd	ra,8(sp)
    80000dc6:	e022                	sd	s0,0(sp)
    80000dc8:	0800                	add	s0,sp,16
    printf(CLEAR_LINE);
    80000dca:	00003517          	auipc	a0,0x3
    80000dce:	ffe50513          	add	a0,a0,-2 # 80003dc8 <etext+0xdc8>
    80000dd2:	1c2000ef          	jal	80000f94 <printf>
}
    80000dd6:	60a2                	ld	ra,8(sp)
    80000dd8:	6402                	ld	s0,0(sp)
    80000dda:	0141                	add	sp,sp,16
    80000ddc:	8082                	ret

0000000080000dde <cursor_home>:

// 将光标移动到终端左上角 (1,1)
void cursor_home(void) {
    80000dde:	1141                	add	sp,sp,-16
    80000de0:	e406                	sd	ra,8(sp)
    80000de2:	e022                	sd	s0,0(sp)
    80000de4:	0800                	add	s0,sp,16
    printf(CURSOR_HOME);
    80000de6:	00003517          	auipc	a0,0x3
    80000dea:	fea50513          	add	a0,a0,-22 # 80003dd0 <etext+0xdd0>
    80000dee:	1a6000ef          	jal	80000f94 <printf>
}
    80000df2:	60a2                	ld	ra,8(sp)
    80000df4:	6402                	ld	s0,0(sp)
    80000df6:	0141                	add	sp,sp,16
    80000df8:	8082                	ret

0000000080000dfa <cursor_hide>:

// 隐藏光标
void cursor_hide(void) {
    80000dfa:	1141                	add	sp,sp,-16
    80000dfc:	e406                	sd	ra,8(sp)
    80000dfe:	e022                	sd	s0,0(sp)
    80000e00:	0800                	add	s0,sp,16
    printf(CURSOR_HIDE);
    80000e02:	00003517          	auipc	a0,0x3
    80000e06:	fd650513          	add	a0,a0,-42 # 80003dd8 <etext+0xdd8>
    80000e0a:	18a000ef          	jal	80000f94 <printf>
}
    80000e0e:	60a2                	ld	ra,8(sp)
    80000e10:	6402                	ld	s0,0(sp)
    80000e12:	0141                	add	sp,sp,16
    80000e14:	8082                	ret

0000000080000e16 <cursor_show>:

// 显示光标
void cursor_show(void) {
    80000e16:	1141                	add	sp,sp,-16
    80000e18:	e406                	sd	ra,8(sp)
    80000e1a:	e022                	sd	s0,0(sp)
    80000e1c:	0800                	add	s0,sp,16
    printf(CURSOR_SHOW);
    80000e1e:	00003517          	auipc	a0,0x3
    80000e22:	fc250513          	add	a0,a0,-62 # 80003de0 <etext+0xde0>
    80000e26:	16e000ef          	jal	80000f94 <printf>
}
    80000e2a:	60a2                	ld	ra,8(sp)
    80000e2c:	6402                	ld	s0,0(sp)
    80000e2e:	0141                	add	sp,sp,16
    80000e30:	8082                	ret

0000000080000e32 <cursor_save>:

// 保存当前光标位置
void cursor_save(void) {
    80000e32:	1141                	add	sp,sp,-16
    80000e34:	e406                	sd	ra,8(sp)
    80000e36:	e022                	sd	s0,0(sp)
    80000e38:	0800                	add	s0,sp,16
    printf(CURSOR_SAVE);
    80000e3a:	00003517          	auipc	a0,0x3
    80000e3e:	fae50513          	add	a0,a0,-82 # 80003de8 <etext+0xde8>
    80000e42:	152000ef          	jal	80000f94 <printf>
}
    80000e46:	60a2                	ld	ra,8(sp)
    80000e48:	6402                	ld	s0,0(sp)
    80000e4a:	0141                	add	sp,sp,16
    80000e4c:	8082                	ret

0000000080000e4e <cursor_restore>:

// 恢复之前保存的光标位置
void cursor_restore(void) {
    80000e4e:	1141                	add	sp,sp,-16
    80000e50:	e406                	sd	ra,8(sp)
    80000e52:	e022                	sd	s0,0(sp)
    80000e54:	0800                	add	s0,sp,16
    printf(CURSOR_RESTORE);
    80000e56:	00003517          	auipc	a0,0x3
    80000e5a:	f9a50513          	add	a0,a0,-102 # 80003df0 <etext+0xdf0>
    80000e5e:	136000ef          	jal	80000f94 <printf>
}
    80000e62:	60a2                	ld	ra,8(sp)
    80000e64:	6402                	ld	s0,0(sp)
    80000e66:	0141                	add	sp,sp,16
    80000e68:	8082                	ret

0000000080000e6a <set_cursor_position>:

// 设置光标绝对位置 (行号, 列号)，从1开始计数
void set_cursor_position(int row, int col) {
    80000e6a:	1141                	add	sp,sp,-16
    80000e6c:	e406                	sd	ra,8(sp)
    80000e6e:	e022                	sd	s0,0(sp)
    80000e70:	0800                	add	s0,sp,16
    80000e72:	862e                	mv	a2,a1
    printf(ESC "%d;%dH", row, col);
    80000e74:	85aa                	mv	a1,a0
    80000e76:	00003517          	auipc	a0,0x3
    80000e7a:	f8250513          	add	a0,a0,-126 # 80003df8 <etext+0xdf8>
    80000e7e:	116000ef          	jal	80000f94 <printf>
}
    80000e82:	60a2                	ld	ra,8(sp)
    80000e84:	6402                	ld	s0,0(sp)
    80000e86:	0141                	add	sp,sp,16
    80000e88:	8082                	ret

0000000080000e8a <move_cursor_up>:

// 光标上移 n 行
void move_cursor_up(int n) {
    80000e8a:	1141                	add	sp,sp,-16
    80000e8c:	e406                	sd	ra,8(sp)
    80000e8e:	e022                	sd	s0,0(sp)
    80000e90:	0800                	add	s0,sp,16
    80000e92:	85aa                	mv	a1,a0
    printf(ESC "%dA", n);
    80000e94:	00003517          	auipc	a0,0x3
    80000e98:	f7450513          	add	a0,a0,-140 # 80003e08 <etext+0xe08>
    80000e9c:	0f8000ef          	jal	80000f94 <printf>
}
    80000ea0:	60a2                	ld	ra,8(sp)
    80000ea2:	6402                	ld	s0,0(sp)
    80000ea4:	0141                	add	sp,sp,16
    80000ea6:	8082                	ret

0000000080000ea8 <move_cursor_down>:

// 光标下移 n 行
void move_cursor_down(int n) {
    80000ea8:	1141                	add	sp,sp,-16
    80000eaa:	e406                	sd	ra,8(sp)
    80000eac:	e022                	sd	s0,0(sp)
    80000eae:	0800                	add	s0,sp,16
    80000eb0:	85aa                	mv	a1,a0
    printf(ESC "%dB", n);
    80000eb2:	00003517          	auipc	a0,0x3
    80000eb6:	f5e50513          	add	a0,a0,-162 # 80003e10 <etext+0xe10>
    80000eba:	0da000ef          	jal	80000f94 <printf>
}
    80000ebe:	60a2                	ld	ra,8(sp)
    80000ec0:	6402                	ld	s0,0(sp)
    80000ec2:	0141                	add	sp,sp,16
    80000ec4:	8082                	ret

0000000080000ec6 <move_cursor_forward>:

// 光标右移（前进）n 列
void move_cursor_forward(int n) {
    80000ec6:	1141                	add	sp,sp,-16
    80000ec8:	e406                	sd	ra,8(sp)
    80000eca:	e022                	sd	s0,0(sp)
    80000ecc:	0800                	add	s0,sp,16
    80000ece:	85aa                	mv	a1,a0
    printf(ESC "%dC", n);
    80000ed0:	00003517          	auipc	a0,0x3
    80000ed4:	f4850513          	add	a0,a0,-184 # 80003e18 <etext+0xe18>
    80000ed8:	0bc000ef          	jal	80000f94 <printf>
}
    80000edc:	60a2                	ld	ra,8(sp)
    80000ede:	6402                	ld	s0,0(sp)
    80000ee0:	0141                	add	sp,sp,16
    80000ee2:	8082                	ret

0000000080000ee4 <move_cursor_back>:

// 光标左移（后退）n 列
void move_cursor_back(int n) {
    80000ee4:	1141                	add	sp,sp,-16
    80000ee6:	e406                	sd	ra,8(sp)
    80000ee8:	e022                	sd	s0,0(sp)
    80000eea:	0800                	add	s0,sp,16
    80000eec:	85aa                	mv	a1,a0
    printf(ESC "%dD", n);
    80000eee:	00003517          	auipc	a0,0x3
    80000ef2:	f3250513          	add	a0,a0,-206 # 80003e20 <etext+0xe20>
    80000ef6:	09e000ef          	jal	80000f94 <printf>
    80000efa:	60a2                	ld	ra,8(sp)
    80000efc:	6402                	ld	s0,0(sp)
    80000efe:	0141                	add	sp,sp,16
    80000f00:	8082                	ret

0000000080000f02 <print_number>:
 * @param num   要打印的数字
 * @param base  进制基数
 * @param sign  是否是有符号数（1表示有符号，0表示无符号）
 */
static void print_number(long long num, int base, int sign)
{
    80000f02:	7139                	add	sp,sp,-64
    80000f04:	fc06                	sd	ra,56(sp)
    80000f06:	f822                	sd	s0,48(sp)
    80000f08:	f426                	sd	s1,40(sp)
    80000f0a:	f04a                	sd	s2,32(sp)
    80000f0c:	0080                	add	s0,sp,64
  char buf[20];
  int i;
  unsigned long long x;

  if(sign && (sign = (num < 0)))
    80000f0e:	c219                	beqz	a2,80000f14 <print_number+0x12>
    80000f10:	06054e63          	bltz	a0,80000f8c <print_number+0x8a>
    x = -num;
  else
    x = num;
    80000f14:	4881                	li	a7,0
    80000f16:	fc840693          	add	a3,s0,-56

  // 将数字转换为指定进制的字符串（逆序存储）
  i = 0;
    80000f1a:	4781                	li	a5,0
  do {
    buf[i++] = digits[x % base];
    80000f1c:	00003617          	auipc	a2,0x3
    80000f20:	f3460613          	add	a2,a2,-204 # 80003e50 <digits>
    80000f24:	883e                	mv	a6,a5
    80000f26:	2785                	addw	a5,a5,1
    80000f28:	02b57733          	remu	a4,a0,a1
    80000f2c:	9732                	add	a4,a4,a2
    80000f2e:	00074703          	lbu	a4,0(a4)
    80000f32:	00e68023          	sb	a4,0(a3)
  } while((x /= base) != 0);
    80000f36:	872a                	mv	a4,a0
    80000f38:	02b55533          	divu	a0,a0,a1
    80000f3c:	0685                	add	a3,a3,1
    80000f3e:	feb773e3          	bgeu	a4,a1,80000f24 <print_number+0x22>

  if(sign)
    80000f42:	00088a63          	beqz	a7,80000f56 <print_number+0x54>
    buf[i++] = '-';
    80000f46:	1781                	add	a5,a5,-32
    80000f48:	97a2                	add	a5,a5,s0
    80000f4a:	02d00713          	li	a4,45
    80000f4e:	fee78423          	sb	a4,-24(a5)
    80000f52:	0028079b          	addw	a5,a6,2
  
   // 逆序输出
  while(--i >= 0)
    80000f56:	02f05563          	blez	a5,80000f80 <print_number+0x7e>
    80000f5a:	fc840713          	add	a4,s0,-56
    80000f5e:	00f704b3          	add	s1,a4,a5
    80000f62:	fff70913          	add	s2,a4,-1
    80000f66:	993e                	add	s2,s2,a5
    80000f68:	37fd                	addw	a5,a5,-1
    80000f6a:	1782                	sll	a5,a5,0x20
    80000f6c:	9381                	srl	a5,a5,0x20
    80000f6e:	40f90933          	sub	s2,s2,a5
    console_putc(buf[i]);
    80000f72:	fff4c503          	lbu	a0,-1(s1)
    80000f76:	135000ef          	jal	800018aa <console_putc>
  while(--i >= 0)
    80000f7a:	14fd                	add	s1,s1,-1
    80000f7c:	ff249be3          	bne	s1,s2,80000f72 <print_number+0x70>
}
    80000f80:	70e2                	ld	ra,56(sp)
    80000f82:	7442                	ld	s0,48(sp)
    80000f84:	74a2                	ld	s1,40(sp)
    80000f86:	7902                	ld	s2,32(sp)
    80000f88:	6121                	add	sp,sp,64
    80000f8a:	8082                	ret
    x = -num;
    80000f8c:	40a00533          	neg	a0,a0
  if(sign && (sign = (num < 0)))
    80000f90:	4885                	li	a7,1
    x = -num;
    80000f92:	b751                	j	80000f16 <print_number+0x14>

0000000080000f94 <printf>:
 * @param fmt  格式字符串
 * @param ...  可变参数
 * @return     总是返回0
 */
int printf(char *fmt, ...)
{
    80000f94:	7135                	add	sp,sp,-160
    80000f96:	ec86                	sd	ra,88(sp)
    80000f98:	e8a2                	sd	s0,80(sp)
    80000f9a:	e4a6                	sd	s1,72(sp)
    80000f9c:	e0ca                	sd	s2,64(sp)
    80000f9e:	fc4e                	sd	s3,56(sp)
    80000fa0:	f852                	sd	s4,48(sp)
    80000fa2:	f456                	sd	s5,40(sp)
    80000fa4:	f05a                	sd	s6,32(sp)
    80000fa6:	ec5e                	sd	s7,24(sp)
    80000fa8:	e862                	sd	s8,16(sp)
    80000faa:	1080                	add	s0,sp,96
    80000fac:	892a                	mv	s2,a0
    80000fae:	e40c                	sd	a1,8(s0)
    80000fb0:	e810                	sd	a2,16(s0)
    80000fb2:	ec14                	sd	a3,24(s0)
    80000fb4:	f018                	sd	a4,32(s0)
    80000fb6:	f41c                	sd	a5,40(s0)
    80000fb8:	03043823          	sd	a6,48(s0)
    80000fbc:	03143c23          	sd	a7,56(s0)
  va_list ap;//可变参数列表
  int i, cx, c0 ; // c1, c2;// 循环变量和字符临时变量
  char *s;

  va_start(ap, fmt);// 初始化可变参数列表
    80000fc0:	00840793          	add	a5,s0,8
    80000fc4:	faf43423          	sd	a5,-88(s0)
  //遍历格式化字符串
  for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
    80000fc8:	00054503          	lbu	a0,0(a0)
    80000fcc:	0e050963          	beqz	a0,800010be <printf+0x12a>
    80000fd0:	0005079b          	sext.w	a5,a0
    80000fd4:	4481                	li	s1,0
    if(cx != '%'){
    80000fd6:	02500993          	li	s3,37
    i++;
    c0 = fmt[i+0] & 0xff;// 第一个格式字符
    //c1 = c2 = 0;
    // if(c0) c1 = fmt[i+1] & 0xff;// 第二个字符（如果有）
    // if(c1) c2 = fmt[i+2] & 0xff;// 第三个字符（如果有）
    if(c0 == 'd'){// 有符号十进制整数
    80000fda:	06400a13          	li	s4,100
      print_number(va_arg(ap, int), 10, 1);
    } else if(c0 == 'x'){// 十六进制无符号整数
    80000fde:	07800a93          	li	s5,120
      print_number(va_arg(ap, uint32), 16, 0);
    } else if(c0 == 'c'){// 字符
    80000fe2:	06300b13          	li	s6,99
      console_putc(va_arg(ap, uint));
    } else if(c0 == 's'){// 字符串
    80000fe6:	07300b93          	li	s7,115
    80000fea:	a819                	j	80001000 <printf+0x6c>
      console_putc(cx);
    80000fec:	0bf000ef          	jal	800018aa <console_putc>
  for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
    80000ff0:	2485                	addw	s1,s1,1
    80000ff2:	009907b3          	add	a5,s2,s1
    80000ff6:	0007c503          	lbu	a0,0(a5)
    80000ffa:	0005079b          	sext.w	a5,a0
    80000ffe:	c161                	beqz	a0,800010be <printf+0x12a>
    if(cx != '%'){
    80001000:	ff3796e3          	bne	a5,s3,80000fec <printf+0x58>
    i++;
    80001004:	2485                	addw	s1,s1,1
    c0 = fmt[i+0] & 0xff;// 第一个格式字符
    80001006:	009907b3          	add	a5,s2,s1
    8000100a:	0007cc03          	lbu	s8,0(a5)
    8000100e:	000c079b          	sext.w	a5,s8
    if(c0 == 'd'){// 有符号十进制整数
    80001012:	03478263          	beq	a5,s4,80001036 <printf+0xa2>
    } else if(c0 == 'x'){// 十六进制无符号整数
    80001016:	03578c63          	beq	a5,s5,8000104e <printf+0xba>
    } else if(c0 == 'c'){// 字符
    8000101a:	05678763          	beq	a5,s6,80001068 <printf+0xd4>
    } else if(c0 == 's'){// 字符串
    8000101e:	07778063          	beq	a5,s7,8000107e <printf+0xea>
      if((s = va_arg(ap, char*)) == 0)
        s = "(null)";// 处理空指针情况
      for(; *s; s++)
        console_putc(*s);
    } else if(c0 == '%'){
    80001022:	09378963          	beq	a5,s3,800010b4 <printf+0x120>
      console_putc('%');
    } else if(c0 == 0){
    80001026:	cfc1                	beqz	a5,800010be <printf+0x12a>
      break;
    } else {
      // 打印未知的%序列以引起注意
      console_putc('%');
    80001028:	854e                	mv	a0,s3
    8000102a:	081000ef          	jal	800018aa <console_putc>
      console_putc(c0);
    8000102e:	8562                	mv	a0,s8
    80001030:	07b000ef          	jal	800018aa <console_putc>
    80001034:	bf75                	j	80000ff0 <printf+0x5c>
      print_number(va_arg(ap, int), 10, 1);
    80001036:	fa843783          	ld	a5,-88(s0)
    8000103a:	00878713          	add	a4,a5,8
    8000103e:	fae43423          	sd	a4,-88(s0)
    80001042:	4605                	li	a2,1
    80001044:	45a9                	li	a1,10
    80001046:	4388                	lw	a0,0(a5)
    80001048:	ebbff0ef          	jal	80000f02 <print_number>
    8000104c:	b755                	j	80000ff0 <printf+0x5c>
      print_number(va_arg(ap, uint32), 16, 0);
    8000104e:	fa843783          	ld	a5,-88(s0)
    80001052:	00878713          	add	a4,a5,8
    80001056:	fae43423          	sd	a4,-88(s0)
    8000105a:	4601                	li	a2,0
    8000105c:	45c1                	li	a1,16
    8000105e:	0007e503          	lwu	a0,0(a5)
    80001062:	ea1ff0ef          	jal	80000f02 <print_number>
    80001066:	b769                	j	80000ff0 <printf+0x5c>
      console_putc(va_arg(ap, uint));
    80001068:	fa843783          	ld	a5,-88(s0)
    8000106c:	00878713          	add	a4,a5,8
    80001070:	fae43423          	sd	a4,-88(s0)
    80001074:	0007c503          	lbu	a0,0(a5)
    80001078:	033000ef          	jal	800018aa <console_putc>
    8000107c:	bf95                	j	80000ff0 <printf+0x5c>
      if((s = va_arg(ap, char*)) == 0)
    8000107e:	fa843783          	ld	a5,-88(s0)
    80001082:	00878713          	add	a4,a5,8
    80001086:	fae43423          	sd	a4,-88(s0)
    8000108a:	0007bc03          	ld	s8,0(a5)
    8000108e:	000c0c63          	beqz	s8,800010a6 <printf+0x112>
      for(; *s; s++)
    80001092:	000c4503          	lbu	a0,0(s8)
    80001096:	dd29                	beqz	a0,80000ff0 <printf+0x5c>
        console_putc(*s);
    80001098:	013000ef          	jal	800018aa <console_putc>
      for(; *s; s++)
    8000109c:	0c05                	add	s8,s8,1
    8000109e:	000c4503          	lbu	a0,0(s8)
    800010a2:	f97d                	bnez	a0,80001098 <printf+0x104>
    800010a4:	b7b1                	j	80000ff0 <printf+0x5c>
        s = "(null)";// 处理空指针情况
    800010a6:	00003c17          	auipc	s8,0x3
    800010aa:	d82c0c13          	add	s8,s8,-638 # 80003e28 <etext+0xe28>
      for(; *s; s++)
    800010ae:	02800513          	li	a0,40
    800010b2:	b7dd                	j	80001098 <printf+0x104>
      console_putc('%');
    800010b4:	02500513          	li	a0,37
    800010b8:	7f2000ef          	jal	800018aa <console_putc>
    800010bc:	bf15                	j	80000ff0 <printf+0x5c>
    }
  }
  va_end(ap);

  return 0;
}
    800010be:	4501                	li	a0,0
    800010c0:	60e6                	ld	ra,88(sp)
    800010c2:	6446                	ld	s0,80(sp)
    800010c4:	64a6                	ld	s1,72(sp)
    800010c6:	6906                	ld	s2,64(sp)
    800010c8:	79e2                	ld	s3,56(sp)
    800010ca:	7a42                	ld	s4,48(sp)
    800010cc:	7aa2                	ld	s5,40(sp)
    800010ce:	7b02                	ld	s6,32(sp)
    800010d0:	6be2                	ld	s7,24(sp)
    800010d2:	6c42                	ld	s8,16(sp)
    800010d4:	610d                	add	sp,sp,160
    800010d6:	8082                	ret

00000000800010d8 <printf_init>:

void printf_init(void)
{
    800010d8:	1141                	add	sp,sp,-16
    800010da:	e406                	sd	ra,8(sp)
    800010dc:	e022                	sd	s0,0(sp)
    800010de:	0800                	add	s0,sp,16
    console_init();
    800010e0:	007000ef          	jal	800018e6 <console_init>
    printf("Printf system initialized.\n");
    800010e4:	00003517          	auipc	a0,0x3
    800010e8:	d4c50513          	add	a0,a0,-692 # 80003e30 <etext+0xe30>
    800010ec:	ea9ff0ef          	jal	80000f94 <printf>
    800010f0:	60a2                	ld	ra,8(sp)
    800010f2:	6402                	ld	s0,0(sp)
    800010f4:	0141                	add	sp,sp,16
    800010f6:	8082                	ret

00000000800010f8 <test_basic_printf>:

// printf功能测试套件
// 验证各种格式化输出和边界条件

void test_basic_printf(void)
{
    800010f8:	1141                	add	sp,sp,-16
    800010fa:	e406                	sd	ra,8(sp)
    800010fc:	e022                	sd	s0,0(sp)
    800010fe:	0800                	add	s0,sp,16
    printf("=== 基本printf测试 ===\n");
    80001100:	00003517          	auipc	a0,0x3
    80001104:	d6850513          	add	a0,a0,-664 # 80003e68 <digits+0x18>
    80001108:	e8dff0ef          	jal	80000f94 <printf>
    
    // 基本字符串输出
    printf("Hello, World!\n");
    8000110c:	00003517          	auipc	a0,0x3
    80001110:	d7c50513          	add	a0,a0,-644 # 80003e88 <digits+0x38>
    80001114:	e81ff0ef          	jal	80000f94 <printf>
    printf("字符串测试: %s\n", "riscv-os");
    80001118:	00003597          	auipc	a1,0x3
    8000111c:	d8058593          	add	a1,a1,-640 # 80003e98 <digits+0x48>
    80001120:	00003517          	auipc	a0,0x3
    80001124:	d8850513          	add	a0,a0,-632 # 80003ea8 <digits+0x58>
    80001128:	e6dff0ef          	jal	80000f94 <printf>
    printf("字符测试: %c\n", 'A');
    8000112c:	04100593          	li	a1,65
    80001130:	00003517          	auipc	a0,0x3
    80001134:	d9050513          	add	a0,a0,-624 # 80003ec0 <digits+0x70>
    80001138:	e5dff0ef          	jal	80000f94 <printf>
    printf("百分号测试: %%\n");
    8000113c:	00003517          	auipc	a0,0x3
    80001140:	d9c50513          	add	a0,a0,-612 # 80003ed8 <digits+0x88>
    80001144:	e51ff0ef          	jal	80000f94 <printf>
    80001148:	3b9ad7b7          	lui	a5,0x3b9ad
    8000114c:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>
    for (int i = 0; i < 1000000000; i++)
    80001150:	37fd                	addw	a5,a5,-1
    80001152:	fffd                	bnez	a5,80001150 <test_basic_printf+0x58>
    {
        /* code */
    }
    
}
    80001154:	60a2                	ld	ra,8(sp)
    80001156:	6402                	ld	s0,0(sp)
    80001158:	0141                	add	sp,sp,16
    8000115a:	8082                	ret

000000008000115c <test_integer_formats>:

void test_integer_formats(void)
{
    8000115c:	1141                	add	sp,sp,-16
    8000115e:	e406                	sd	ra,8(sp)
    80001160:	e022                	sd	s0,0(sp)
    80001162:	0800                	add	s0,sp,16
    printf("\n=== 整数格式测试 ===\n");
    80001164:	00003517          	auipc	a0,0x3
    80001168:	d8c50513          	add	a0,a0,-628 # 80003ef0 <digits+0xa0>
    8000116c:	e29ff0ef          	jal	80000f94 <printf>
    
    // 十进制测试
    printf("正数: %d\n", 42);
    80001170:	02a00593          	li	a1,42
    80001174:	00003517          	auipc	a0,0x3
    80001178:	d9c50513          	add	a0,a0,-612 # 80003f10 <digits+0xc0>
    8000117c:	e19ff0ef          	jal	80000f94 <printf>
    printf("负数: %d\n", -42);
    80001180:	fd600593          	li	a1,-42
    80001184:	00003517          	auipc	a0,0x3
    80001188:	d9c50513          	add	a0,a0,-612 # 80003f20 <digits+0xd0>
    8000118c:	e09ff0ef          	jal	80000f94 <printf>
    printf("零: %d\n", 0);
    80001190:	4581                	li	a1,0
    80001192:	00003517          	auipc	a0,0x3
    80001196:	d9e50513          	add	a0,a0,-610 # 80003f30 <digits+0xe0>
    8000119a:	dfbff0ef          	jal	80000f94 <printf>
    
    // 十六进制测试
    printf("十六进制: %x\n", 255);
    8000119e:	0ff00593          	li	a1,255
    800011a2:	00003517          	auipc	a0,0x3
    800011a6:	d9e50513          	add	a0,a0,-610 # 80003f40 <digits+0xf0>
    800011aa:	debff0ef          	jal	80000f94 <printf>
    printf("十六进制大数: %x\n", 0xDEADBEEF);
    800011ae:	deadc5b7          	lui	a1,0xdeadc
    800011b2:	eef58593          	add	a1,a1,-273 # ffffffffdeadbeef <tests_passed+0xffffffff5ead5dbb>
    800011b6:	00003517          	auipc	a0,0x3
    800011ba:	da250513          	add	a0,a0,-606 # 80003f58 <digits+0x108>
    800011be:	dd7ff0ef          	jal	80000f94 <printf>
    
    // 无符号数测试
    printf("无符号数: %u\n", 4294967295U);
    800011c2:	55fd                	li	a1,-1
    800011c4:	00003517          	auipc	a0,0x3
    800011c8:	dac50513          	add	a0,a0,-596 # 80003f70 <digits+0x120>
    800011cc:	dc9ff0ef          	jal	80000f94 <printf>
    800011d0:	3b9ad7b7          	lui	a5,0x3b9ad
    800011d4:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    800011d8:	37fd                	addw	a5,a5,-1
    800011da:	fffd                	bnez	a5,800011d8 <test_integer_formats+0x7c>
    {
        /* code */
    }
    
}
    800011dc:	60a2                	ld	ra,8(sp)
    800011de:	6402                	ld	s0,0(sp)
    800011e0:	0141                	add	sp,sp,16
    800011e2:	8082                	ret

00000000800011e4 <test_boundary_conditions>:

void test_boundary_conditions(void)
{
    800011e4:	7179                	add	sp,sp,-48
    800011e6:	f406                	sd	ra,40(sp)
    800011e8:	f022                	sd	s0,32(sp)
    800011ea:	ec26                	sd	s1,24(sp)
    800011ec:	1800                	add	s0,sp,48
    printf("\n=== 边界条件测试 ===\n");
    800011ee:	00003517          	auipc	a0,0x3
    800011f2:	d9a50513          	add	a0,a0,-614 # 80003f88 <digits+0x138>
    800011f6:	d9fff0ef          	jal	80000f94 <printf>
    
    // INT_MIN和INT_MAX测试
    printf("INT_MIN: %d\n", -2147483647-1);  // 避免编译器警告
    800011fa:	800005b7          	lui	a1,0x80000
    800011fe:	00003517          	auipc	a0,0x3
    80001202:	daa50513          	add	a0,a0,-598 # 80003fa8 <digits+0x158>
    80001206:	d8fff0ef          	jal	80000f94 <printf>
    printf("INT_MAX: %d\n", 2147483647);
    8000120a:	800005b7          	lui	a1,0x80000
    8000120e:	fff5c593          	not	a1,a1
    80001212:	00003517          	auipc	a0,0x3
    80001216:	da650513          	add	a0,a0,-602 # 80003fb8 <digits+0x168>
    8000121a:	d7bff0ef          	jal	80000f94 <printf>
    
    // 长整型测试
    printf("长整型: %ld\n", 9223372036854775807LL);
    8000121e:	54fd                	li	s1,-1
    80001220:	0014d593          	srl	a1,s1,0x1
    80001224:	00003517          	auipc	a0,0x3
    80001228:	da450513          	add	a0,a0,-604 # 80003fc8 <digits+0x178>
    8000122c:	d69ff0ef          	jal	80000f94 <printf>
    printf("长整型负数: %ld\n", -9223372036854775807LL-1);  // 避免编译器警告
    80001230:	03f49593          	sll	a1,s1,0x3f
    80001234:	00003517          	auipc	a0,0x3
    80001238:	da450513          	add	a0,a0,-604 # 80003fd8 <digits+0x188>
    8000123c:	d59ff0ef          	jal	80000f94 <printf>
    
    // 指针测试
    int x = 42;
    80001240:	02a00793          	li	a5,42
    80001244:	fcf42e23          	sw	a5,-36(s0)
    printf("指针: %p\n", &x);
    80001248:	fdc40593          	add	a1,s0,-36
    8000124c:	00003517          	auipc	a0,0x3
    80001250:	da450513          	add	a0,a0,-604 # 80003ff0 <digits+0x1a0>
    80001254:	d41ff0ef          	jal	80000f94 <printf>
    
    // NULL指针测试
    printf("NULL字符串: %s\n", (char*)0);
    80001258:	4581                	li	a1,0
    8000125a:	00003517          	auipc	a0,0x3
    8000125e:	da650513          	add	a0,a0,-602 # 80004000 <digits+0x1b0>
    80001262:	d33ff0ef          	jal	80000f94 <printf>
    80001266:	3b9ad7b7          	lui	a5,0x3b9ad
    8000126a:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    8000126e:	37fd                	addw	a5,a5,-1
    80001270:	fffd                	bnez	a5,8000126e <test_boundary_conditions+0x8a>
    {
        /* code */
    }
    
}
    80001272:	70a2                	ld	ra,40(sp)
    80001274:	7402                	ld	s0,32(sp)
    80001276:	64e2                	ld	s1,24(sp)
    80001278:	6145                	add	sp,sp,48
    8000127a:	8082                	ret

000000008000127c <test_format_edge_cases>:

void test_format_edge_cases(void)
{
    8000127c:	1141                	add	sp,sp,-16
    8000127e:	e406                	sd	ra,8(sp)
    80001280:	e022                	sd	s0,0(sp)
    80001282:	0800                	add	s0,sp,16
    printf("\n=== 格式边界测试 ===\n");
    80001284:	00003517          	auipc	a0,0x3
    80001288:	d9450513          	add	a0,a0,-620 # 80004018 <digits+0x1c8>
    8000128c:	d09ff0ef          	jal	80000f94 <printf>
    
    // 连续格式符
    printf("连续格式: %d %d %d\n", 1, 2, 3);
    80001290:	468d                	li	a3,3
    80001292:	4609                	li	a2,2
    80001294:	4585                	li	a1,1
    80001296:	00003517          	auipc	a0,0x3
    8000129a:	da250513          	add	a0,a0,-606 # 80004038 <digits+0x1e8>
    8000129e:	cf7ff0ef          	jal	80000f94 <printf>
    
    // 混合格式
    printf("混合: %s有%d个%c，十六进制是%x\n", "测试", 10, 'A', 10);
    800012a2:	4729                	li	a4,10
    800012a4:	04100693          	li	a3,65
    800012a8:	4629                	li	a2,10
    800012aa:	00003597          	auipc	a1,0x3
    800012ae:	da658593          	add	a1,a1,-602 # 80004050 <digits+0x200>
    800012b2:	00003517          	auipc	a0,0x3
    800012b6:	da650513          	add	a0,a0,-602 # 80004058 <digits+0x208>
    800012ba:	cdbff0ef          	jal	80000f94 <printf>
    
    // 未知格式符测试
    printf("未知格式: %z %q\n");
    800012be:	00003517          	auipc	a0,0x3
    800012c2:	dca50513          	add	a0,a0,-566 # 80004088 <digits+0x238>
    800012c6:	ccfff0ef          	jal	80000f94 <printf>
    
    // 格式字符串结尾是%
    printf("结尾百分号: test%");
    800012ca:	00003517          	auipc	a0,0x3
    800012ce:	dd650513          	add	a0,a0,-554 # 800040a0 <digits+0x250>
    800012d2:	cc3ff0ef          	jal	80000f94 <printf>
    printf("\n");
    800012d6:	00003517          	auipc	a0,0x3
    800012da:	9b250513          	add	a0,a0,-1614 # 80003c88 <etext+0xc88>
    800012de:	cb7ff0ef          	jal	80000f94 <printf>
    800012e2:	3b9ad7b7          	lui	a5,0x3b9ad
    800012e6:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    800012ea:	37fd                	addw	a5,a5,-1
    800012ec:	fffd                	bnez	a5,800012ea <test_format_edge_cases+0x6e>
    {
        /* code */
    }
    
}
    800012ee:	60a2                	ld	ra,8(sp)
    800012f0:	6402                	ld	s0,0(sp)
    800012f2:	0141                	add	sp,sp,16
    800012f4:	8082                	ret

00000000800012f6 <test_number_conversion_algorithm>:

void test_number_conversion_algorithm(void)
{
    800012f6:	7179                	add	sp,sp,-48
    800012f8:	f406                	sd	ra,40(sp)
    800012fa:	f022                	sd	s0,32(sp)
    800012fc:	ec26                	sd	s1,24(sp)
    800012fe:	e84a                	sd	s2,16(sp)
    80001300:	e44e                	sd	s3,8(sp)
    80001302:	1800                	add	s0,sp,48
    printf("\n=== 数字转换算法测试 ===\n");
    80001304:	00003517          	auipc	a0,0x3
    80001308:	db450513          	add	a0,a0,-588 # 800040b8 <digits+0x268>
    8000130c:	c89ff0ef          	jal	80000f94 <printf>
    
    // 各种进制测试
    printf("二进制模拟(用十六进制): %x\n", 0b11111111); // 如果支持
    80001310:	0ff00593          	li	a1,255
    80001314:	00003517          	auipc	a0,0x3
    80001318:	dcc50513          	add	a0,a0,-564 # 800040e0 <digits+0x290>
    8000131c:	c79ff0ef          	jal	80000f94 <printf>
    printf("八进制模拟(用十六进制): %x\n", 0377);
    80001320:	0ff00593          	li	a1,255
    80001324:	00003517          	auipc	a0,0x3
    80001328:	de450513          	add	a0,a0,-540 # 80004108 <digits+0x2b8>
    8000132c:	c69ff0ef          	jal	80000f94 <printf>
    
    // 大数测试
    printf("大十六进制数: %lx\n", 0x123456789ABCDEFLL);
    80001330:	00004597          	auipc	a1,0x4
    80001334:	c305b583          	ld	a1,-976(a1) # 80004f60 <digits+0xb40>
    80001338:	00003517          	auipc	a0,0x3
    8000133c:	df850513          	add	a0,a0,-520 # 80004130 <digits+0x2e0>
    80001340:	c55ff0ef          	jal	80000f94 <printf>
    
    // 小数测试（如果实现了）
    printf("零值各种格式: %d %x %u\n", 0, 0, 0);
    80001344:	4681                	li	a3,0
    80001346:	4601                	li	a2,0
    80001348:	4581                	li	a1,0
    8000134a:	00003517          	auipc	a0,0x3
    8000134e:	e0650513          	add	a0,a0,-506 # 80004150 <digits+0x300>
    80001352:	c43ff0ef          	jal	80000f94 <printf>
    
    // 单位数测试
    for (int i = 0; i < 10; i++) {
    80001356:	4481                	li	s1,0
        printf("%d ", i);
    80001358:	00003997          	auipc	s3,0x3
    8000135c:	e1898993          	add	s3,s3,-488 # 80004170 <digits+0x320>
    for (int i = 0; i < 10; i++) {
    80001360:	4929                	li	s2,10
        printf("%d ", i);
    80001362:	85a6                	mv	a1,s1
    80001364:	854e                	mv	a0,s3
    80001366:	c2fff0ef          	jal	80000f94 <printf>
    for (int i = 0; i < 10; i++) {
    8000136a:	2485                	addw	s1,s1,1
    8000136c:	ff249be3          	bne	s1,s2,80001362 <test_number_conversion_algorithm+0x6c>
    }
    printf("\n");
    80001370:	00003517          	auipc	a0,0x3
    80001374:	91850513          	add	a0,a0,-1768 # 80003c88 <etext+0xc88>
    80001378:	c1dff0ef          	jal	80000f94 <printf>
    
    // 十六进制字母测试
    for (int i = 10; i < 16; i++) {
        printf("%x ", i);
    8000137c:	00003997          	auipc	s3,0x3
    80001380:	dfc98993          	add	s3,s3,-516 # 80004178 <digits+0x328>
    for (int i = 10; i < 16; i++) {
    80001384:	4941                	li	s2,16
        printf("%x ", i);
    80001386:	85a6                	mv	a1,s1
    80001388:	854e                	mv	a0,s3
    8000138a:	c0bff0ef          	jal	80000f94 <printf>
    for (int i = 10; i < 16; i++) {
    8000138e:	2485                	addw	s1,s1,1
    80001390:	ff249be3          	bne	s1,s2,80001386 <test_number_conversion_algorithm+0x90>
    }
    printf("\n");
    80001394:	00003517          	auipc	a0,0x3
    80001398:	8f450513          	add	a0,a0,-1804 # 80003c88 <etext+0xc88>
    8000139c:	bf9ff0ef          	jal	80000f94 <printf>
    800013a0:	3b9ad7b7          	lui	a5,0x3b9ad
    800013a4:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    800013a8:	37fd                	addw	a5,a5,-1
    800013aa:	fffd                	bnez	a5,800013a8 <test_number_conversion_algorithm+0xb2>
    {
        /* code */
    }
    
}
    800013ac:	70a2                	ld	ra,40(sp)
    800013ae:	7402                	ld	s0,32(sp)
    800013b0:	64e2                	ld	s1,24(sp)
    800013b2:	6942                	ld	s2,16(sp)
    800013b4:	69a2                	ld	s3,8(sp)
    800013b6:	6145                	add	sp,sp,48
    800013b8:	8082                	ret

00000000800013ba <test_console_features>:

void test_console_features(void)
{
    800013ba:	1141                	add	sp,sp,-16
    800013bc:	e406                	sd	ra,8(sp)
    800013be:	e022                	sd	s0,0(sp)
    800013c0:	0800                	add	s0,sp,16
    printf("\n=== 控制台功能测试 ===\n");
    800013c2:	00003517          	auipc	a0,0x3
    800013c6:	dbe50513          	add	a0,a0,-578 # 80004180 <digits+0x330>
    800013ca:	bcbff0ef          	jal	80000f94 <printf>

    //颜色测试
    printf("颜色测试开始:\n");
    800013ce:	00003517          	auipc	a0,0x3
    800013d2:	dd250513          	add	a0,a0,-558 # 800041a0 <digits+0x350>
    800013d6:	bbfff0ef          	jal	80000f94 <printf>
    printf(TEXT_BOLD FG_RED "这是加粗的红色文字" RESET_ALL "\n");
    800013da:	00003517          	auipc	a0,0x3
    800013de:	dde50513          	add	a0,a0,-546 # 800041b8 <digits+0x368>
    800013e2:	bb3ff0ef          	jal	80000f94 <printf>
    printf(FG_GREEN BG_YELLOW "这是绿色文字黄色背景" RESET_ALL "\n");
    800013e6:	00003517          	auipc	a0,0x3
    800013ea:	e0250513          	add	a0,a0,-510 # 800041e8 <digits+0x398>
    800013ee:	ba7ff0ef          	jal	80000f94 <printf>
    printf(TEXT_UNDERLINE FG_BLUE "这是带下划线的蓝色文字" RESET_ALL "\n");
    800013f2:	00003517          	auipc	a0,0x3
    800013f6:	e2650513          	add	a0,a0,-474 # 80004218 <digits+0x3c8>
    800013fa:	b9bff0ef          	jal	80000f94 <printf>
    printf(TEXT_INVERT "这是反色显示的文字" RESET_ALL "\n");
    800013fe:	00003517          	auipc	a0,0x3
    80001402:	e4a50513          	add	a0,a0,-438 # 80004248 <digits+0x3f8>
    80001406:	b8fff0ef          	jal	80000f94 <printf>
    printf("\n");
    8000140a:	00003517          	auipc	a0,0x3
    8000140e:	87e50513          	add	a0,a0,-1922 # 80003c88 <etext+0xc88>
    80001412:	b83ff0ef          	jal	80000f94 <printf>
    80001416:	3b9ad7b7          	lui	a5,0x3b9ad
    8000141a:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>
    // // 清行测试
    // printf("这行将被清除...");
    // clear_line();
    // printf("清除完成\n");

    for (int i = 0; i < 1000000000; i++)
    8000141e:	37fd                	addw	a5,a5,-1
    80001420:	fffd                	bnez	a5,8000141e <test_console_features+0x64>
    {
        /* code */
    }
    
}
    80001422:	60a2                	ld	ra,8(sp)
    80001424:	6402                	ld	s0,0(sp)
    80001426:	0141                	add	sp,sp,16
    80001428:	8082                	ret

000000008000142a <test_performance>:

void test_performance(void)
{
    8000142a:	7139                	add	sp,sp,-64
    8000142c:	fc06                	sd	ra,56(sp)
    8000142e:	f822                	sd	s0,48(sp)
    80001430:	f426                	sd	s1,40(sp)
    80001432:	f04a                	sd	s2,32(sp)
    80001434:	ec4e                	sd	s3,24(sp)
    80001436:	e852                	sd	s4,16(sp)
    80001438:	e456                	sd	s5,8(sp)
    8000143a:	0080                	add	s0,sp,64
    printf("\n=== 性能测试 ===\n");
    8000143c:	00003517          	auipc	a0,0x3
    80001440:	e3450513          	add	a0,a0,-460 # 80004270 <digits+0x420>
    80001444:	b51ff0ef          	jal	80000f94 <printf>
    
    // 大量输出测试
    printf("大量数字输出测试:\n");
    80001448:	00003517          	auipc	a0,0x3
    8000144c:	e4050513          	add	a0,a0,-448 # 80004288 <digits+0x438>
    80001450:	b45ff0ef          	jal	80000f94 <printf>
    for (int i = 0; i < 100; i++) {
    80001454:	4481                	li	s1,0
        if (i % 10 == 0) printf("\n");
    80001456:	4a29                	li	s4,10
    80001458:	00003a97          	auipc	s5,0x3
    8000145c:	830a8a93          	add	s5,s5,-2000 # 80003c88 <etext+0xc88>
        printf("%d ", i);
    80001460:	00003997          	auipc	s3,0x3
    80001464:	d1098993          	add	s3,s3,-752 # 80004170 <digits+0x320>
    for (int i = 0; i < 100; i++) {
    80001468:	06400913          	li	s2,100
    8000146c:	a801                	j	8000147c <test_performance+0x52>
        printf("%d ", i);
    8000146e:	85a6                	mv	a1,s1
    80001470:	854e                	mv	a0,s3
    80001472:	b23ff0ef          	jal	80000f94 <printf>
    for (int i = 0; i < 100; i++) {
    80001476:	2485                	addw	s1,s1,1
    80001478:	01248963          	beq	s1,s2,8000148a <test_performance+0x60>
        if (i % 10 == 0) printf("\n");
    8000147c:	0344e7bb          	remw	a5,s1,s4
    80001480:	f7fd                	bnez	a5,8000146e <test_performance+0x44>
    80001482:	8556                	mv	a0,s5
    80001484:	b11ff0ef          	jal	80000f94 <printf>
    80001488:	b7dd                	j	8000146e <test_performance+0x44>
    }
    printf("\n");
    8000148a:	00002517          	auipc	a0,0x2
    8000148e:	7fe50513          	add	a0,a0,2046 # 80003c88 <etext+0xc88>
    80001492:	b03ff0ef          	jal	80000f94 <printf>
    
    // 长字符串测试
    printf("长字符串测试: ");
    80001496:	00003517          	auipc	a0,0x3
    8000149a:	e1250513          	add	a0,a0,-494 # 800042a8 <digits+0x458>
    8000149e:	af7ff0ef          	jal	80000f94 <printf>
    800014a2:	03200493          	li	s1,50
    for (int i = 0; i < 50; i++) {
        printf("*");
    800014a6:	00003917          	auipc	s2,0x3
    800014aa:	e1a90913          	add	s2,s2,-486 # 800042c0 <digits+0x470>
    800014ae:	854a                	mv	a0,s2
    800014b0:	ae5ff0ef          	jal	80000f94 <printf>
    for (int i = 0; i < 50; i++) {
    800014b4:	34fd                	addw	s1,s1,-1
    800014b6:	fce5                	bnez	s1,800014ae <test_performance+0x84>
    }
    printf("\n");
    800014b8:	00002517          	auipc	a0,0x2
    800014bc:	7d050513          	add	a0,a0,2000 # 80003c88 <etext+0xc88>
    800014c0:	ad5ff0ef          	jal	80000f94 <printf>
    800014c4:	3b9ad7b7          	lui	a5,0x3b9ad
    800014c8:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    800014cc:	37fd                	addw	a5,a5,-1
    800014ce:	fffd                	bnez	a5,800014cc <test_performance+0xa2>
    {
        /* code */
    }
    
}
    800014d0:	70e2                	ld	ra,56(sp)
    800014d2:	7442                	ld	s0,48(sp)
    800014d4:	74a2                	ld	s1,40(sp)
    800014d6:	7902                	ld	s2,32(sp)
    800014d8:	69e2                	ld	s3,24(sp)
    800014da:	6a42                	ld	s4,16(sp)
    800014dc:	6aa2                	ld	s5,8(sp)
    800014de:	6121                	add	sp,sp,64
    800014e0:	8082                	ret

00000000800014e2 <test_error_handling>:

void test_error_handling(void)
{
    800014e2:	1141                	add	sp,sp,-16
    800014e4:	e406                	sd	ra,8(sp)
    800014e6:	e022                	sd	s0,0(sp)
    800014e8:	0800                	add	s0,sp,16
    printf("\n=== 错误处理测试 ===\n");
    800014ea:	00003517          	auipc	a0,0x3
    800014ee:	dde50513          	add	a0,a0,-546 # 800042c8 <digits+0x478>
    800014f2:	aa3ff0ef          	jal	80000f94 <printf>
    
    // 这些测试应该不会崩溃系统
    printf("NULL指针处理: %s\n", (char*)0);
    800014f6:	4581                	li	a1,0
    800014f8:	00003517          	auipc	a0,0x3
    800014fc:	df050513          	add	a0,a0,-528 # 800042e8 <digits+0x498>
    80001500:	a95ff0ef          	jal	80000f94 <printf>
    printf("空字符串: %s\n", "");
    80001504:	00002597          	auipc	a1,0x2
    80001508:	49458593          	add	a1,a1,1172 # 80003998 <etext+0x998>
    8000150c:	00003517          	auipc	a0,0x3
    80001510:	df450513          	add	a0,a0,-524 # 80004300 <digits+0x4b0>
    80001514:	a81ff0ef          	jal	80000f94 <printf>
    
    // 格式不匹配测试（注意：这可能导致未定义行为）
    printf("格式测试完成\n");
    80001518:	00003517          	auipc	a0,0x3
    8000151c:	e0050513          	add	a0,a0,-512 # 80004318 <digits+0x4c8>
    80001520:	a75ff0ef          	jal	80000f94 <printf>
    80001524:	3b9ad7b7          	lui	a5,0x3b9ad
    80001528:	a0078793          	add	a5,a5,-1536 # 3b9aca00 <_entry-0x44653600>

    for (int i = 0; i < 1000000000; i++)
    8000152c:	37fd                	addw	a5,a5,-1
    8000152e:	fffd                	bnez	a5,8000152c <test_error_handling+0x4a>
    {
        /* code */
    }
    
}
    80001530:	60a2                	ld	ra,8(sp)
    80001532:	6402                	ld	s0,0(sp)
    80001534:	0141                	add	sp,sp,16
    80001536:	8082                	ret

0000000080001538 <run_printf_tests>:

// 主测试函数
void run_printf_tests(void)
{
    80001538:	1141                	add	sp,sp,-16
    8000153a:	e406                	sd	ra,8(sp)
    8000153c:	e022                	sd	s0,0(sp)
    8000153e:	0800                	add	s0,sp,16
    printf("\n");
    80001540:	00002517          	auipc	a0,0x2
    80001544:	74850513          	add	a0,a0,1864 # 80003c88 <etext+0xc88>
    80001548:	a4dff0ef          	jal	80000f94 <printf>
    printf("========================================\n");
    8000154c:	00002517          	auipc	a0,0x2
    80001550:	3f450513          	add	a0,a0,1012 # 80003940 <etext+0x940>
    80001554:	a41ff0ef          	jal	80000f94 <printf>
    printf("       RISCV-OS Printf 测试套件        \n");
    80001558:	00003517          	auipc	a0,0x3
    8000155c:	dd850513          	add	a0,a0,-552 # 80004330 <digits+0x4e0>
    80001560:	a35ff0ef          	jal	80000f94 <printf>
    printf("========================================\n");
    80001564:	00002517          	auipc	a0,0x2
    80001568:	3dc50513          	add	a0,a0,988 # 80003940 <etext+0x940>
    8000156c:	a29ff0ef          	jal	80000f94 <printf>

    test_console_features();
    80001570:	e4bff0ef          	jal	800013ba <test_console_features>
    test_basic_printf();
    80001574:	b85ff0ef          	jal	800010f8 <test_basic_printf>
    test_integer_formats();
    80001578:	be5ff0ef          	jal	8000115c <test_integer_formats>
    test_boundary_conditions();
    8000157c:	c69ff0ef          	jal	800011e4 <test_boundary_conditions>
    test_format_edge_cases();
    80001580:	cfdff0ef          	jal	8000127c <test_format_edge_cases>
    test_number_conversion_algorithm();
    80001584:	d73ff0ef          	jal	800012f6 <test_number_conversion_algorithm>
    test_performance();
    80001588:	ea3ff0ef          	jal	8000142a <test_performance>
    test_error_handling();
    8000158c:	f57ff0ef          	jal	800014e2 <test_error_handling>
    
    printf("\n========================================\n");
    80001590:	00003517          	auipc	a0,0x3
    80001594:	dd050513          	add	a0,a0,-560 # 80004360 <digits+0x510>
    80001598:	9fdff0ef          	jal	80000f94 <printf>
    printf("           测试完成！                   \n");
    8000159c:	00003517          	auipc	a0,0x3
    800015a0:	df450513          	add	a0,a0,-524 # 80004390 <digits+0x540>
    800015a4:	9f1ff0ef          	jal	80000f94 <printf>
    printf("========================================\n");
    800015a8:	00002517          	auipc	a0,0x2
    800015ac:	39850513          	add	a0,a0,920 # 80003940 <etext+0x940>
    800015b0:	9e5ff0ef          	jal	80000f94 <printf>
}
    800015b4:	60a2                	ld	ra,8(sp)
    800015b6:	6402                	ld	s0,0(sp)
    800015b8:	0141                	add	sp,sp,16
    800015ba:	8082                	ret

00000000800015bc <demo_clear_screen>:

// 清屏功能演示
void demo_clear_screen(void)
{
    800015bc:	1101                	add	sp,sp,-32
    800015be:	ec06                	sd	ra,24(sp)
    800015c0:	e822                	sd	s0,16(sp)
    800015c2:	1000                	add	s0,sp,32
    printf("清屏演示 - 3秒后清屏...\n");
    800015c4:	00003517          	auipc	a0,0x3
    800015c8:	dfc50513          	add	a0,a0,-516 # 800043c0 <digits+0x570>
    800015cc:	9c9ff0ef          	jal	80000f94 <printf>
    
    // 简单延时（在实际系统中应该使用定时器）
    for (volatile int i = 0; i < 10000000; i++) {
    800015d0:	fe042623          	sw	zero,-20(s0)
    800015d4:	fec42703          	lw	a4,-20(s0)
    800015d8:	2701                	sext.w	a4,a4
    800015da:	009897b7          	lui	a5,0x989
    800015de:	67f78793          	add	a5,a5,1663 # 98967f <_entry-0x7f676981>
    800015e2:	00e7cd63          	blt	a5,a4,800015fc <demo_clear_screen+0x40>
    800015e6:	873e                	mv	a4,a5
    800015e8:	fec42783          	lw	a5,-20(s0)
    800015ec:	2785                	addw	a5,a5,1
    800015ee:	fef42623          	sw	a5,-20(s0)
    800015f2:	fec42783          	lw	a5,-20(s0)
    800015f6:	2781                	sext.w	a5,a5
    800015f8:	fef758e3          	bge	a4,a5,800015e8 <demo_clear_screen+0x2c>
        // 空循环延时
    }
    
    clear_screen();
    800015fc:	faaff0ef          	jal	80000da6 <clear_screen>
    printf("屏幕已清除！\n");
    80001600:	00003517          	auipc	a0,0x3
    80001604:	de850513          	add	a0,a0,-536 # 800043e8 <digits+0x598>
    80001608:	98dff0ef          	jal	80000f94 <printf>
    printf("清屏功能正常工作。\n");
    8000160c:	00003517          	auipc	a0,0x3
    80001610:	df450513          	add	a0,a0,-524 # 80004400 <digits+0x5b0>
    80001614:	981ff0ef          	jal	80000f94 <printf>
    80001618:	60e2                	ld	ra,24(sp)
    8000161a:	6442                	ld	s0,16(sp)
    8000161c:	6105                	add	sp,sp,32
    8000161e:	8082                	ret

0000000080001620 <print_number_to_buf>:
static char digits[] = "0123456789abcdef";

// 将字符写入缓冲区
static int
print_number_to_buf(long long num, int base, int sign, char *buf, int *index)
{
    80001620:	7179                	add	sp,sp,-48
    80001622:	f422                	sd	s0,40(sp)
    80001624:	1800                	add	s0,sp,48
  char local_buf[20];
  int i;
  unsigned long long x;

  if(sign && (sign = (num < 0)))
    80001626:	c219                	beqz	a2,8000162c <print_number_to_buf+0xc>
    80001628:	08054363          	bltz	a0,800016ae <print_number_to_buf+0x8e>
    x = -num;
  else
    x = num;
    8000162c:	4e01                	li	t3,0
    8000162e:	fd840813          	add	a6,s0,-40

  i = 0;
    80001632:	4781                	li	a5,0
  do {
    local_buf[i++] = digits[x % base];
    80001634:	00003897          	auipc	a7,0x3
    80001638:	dec88893          	add	a7,a7,-532 # 80004420 <digits>
    8000163c:	833e                	mv	t1,a5
    8000163e:	2785                	addw	a5,a5,1
    80001640:	02b57633          	remu	a2,a0,a1
    80001644:	9646                	add	a2,a2,a7
    80001646:	00064603          	lbu	a2,0(a2)
    8000164a:	00c80023          	sb	a2,0(a6)
  } while((x /= base) != 0);
    8000164e:	862a                	mv	a2,a0
    80001650:	02b55533          	divu	a0,a0,a1
    80001654:	0805                	add	a6,a6,1
    80001656:	feb673e3          	bgeu	a2,a1,8000163c <print_number_to_buf+0x1c>

  if(sign)
    8000165a:	000e0a63          	beqz	t3,8000166e <print_number_to_buf+0x4e>
    local_buf[i++] = '-';
    8000165e:	17c1                	add	a5,a5,-16
    80001660:	97a2                	add	a5,a5,s0
    80001662:	02d00613          	li	a2,45
    80001666:	fec78423          	sb	a2,-24(a5)
    8000166a:	0023079b          	addw	a5,t1,2

  while(--i >= 0) {
    8000166e:	02f05c63          	blez	a5,800016a6 <print_number_to_buf+0x86>
    80001672:	fd840613          	add	a2,s0,-40
    80001676:	963e                	add	a2,a2,a5
    80001678:	fd740513          	add	a0,s0,-41
    8000167c:	953e                	add	a0,a0,a5
    8000167e:	37fd                	addw	a5,a5,-1
    80001680:	1782                	sll	a5,a5,0x20
    80001682:	9381                	srl	a5,a5,0x20
    80001684:	8d1d                	sub	a0,a0,a5
    if (*index < SPRINTF_BUF_MAX - 1) { 
    80001686:	0fe00813          	li	a6,254
    8000168a:	431c                	lw	a5,0(a4)
    8000168c:	00f84d63          	blt	a6,a5,800016a6 <print_number_to_buf+0x86>
      buf[(*index)++] = local_buf[i];
    80001690:	0017859b          	addw	a1,a5,1
    80001694:	c30c                	sw	a1,0(a4)
    80001696:	97b6                	add	a5,a5,a3
    80001698:	fff64583          	lbu	a1,-1(a2)
    8000169c:	00b78023          	sb	a1,0(a5)
  while(--i >= 0) {
    800016a0:	167d                	add	a2,a2,-1
    800016a2:	fea614e3          	bne	a2,a0,8000168a <print_number_to_buf+0x6a>
    } else {
      break; 
    }
  }
  return 0;
}
    800016a6:	4501                	li	a0,0
    800016a8:	7422                	ld	s0,40(sp)
    800016aa:	6145                	add	sp,sp,48
    800016ac:	8082                	ret
    x = -num;
    800016ae:	40a00533          	neg	a0,a0
  if(sign && (sign = (num < 0)))
    800016b2:	4e05                	li	t3,1
    x = -num;
    800016b4:	bfad                	j	8000162e <print_number_to_buf+0xe>

00000000800016b6 <sprintf>:

int
sprintf(char *buf, const char *fmt, ...)
{
    800016b6:	7119                	add	sp,sp,-128
    800016b8:	e486                	sd	ra,72(sp)
    800016ba:	e0a2                	sd	s0,64(sp)
    800016bc:	fc26                	sd	s1,56(sp)
    800016be:	f84a                	sd	s2,48(sp)
    800016c0:	f44e                	sd	s3,40(sp)
    800016c2:	f052                	sd	s4,32(sp)
    800016c4:	ec56                	sd	s5,24(sp)
    800016c6:	0880                	add	s0,sp,80
    800016c8:	892a                	mv	s2,a0
    800016ca:	e010                	sd	a2,0(s0)
    800016cc:	e414                	sd	a3,8(s0)
    800016ce:	e818                	sd	a4,16(s0)
    800016d0:	ec1c                	sd	a5,24(s0)
    800016d2:	03043023          	sd	a6,32(s0)
    800016d6:	03143423          	sd	a7,40(s0)
  va_list ap;
  int i, cx, c0, c1, c2;
  char *s;
  int buf_index = 0; 
    800016da:	fa042a23          	sw	zero,-76(s0)

  va_start(ap, fmt);
    800016de:	fa843c23          	sd	s0,-72(s0)
  
  for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
    800016e2:	0005c783          	lbu	a5,0(a1)
    800016e6:	cf9d                	beqz	a5,80001724 <sprintf+0x6e>
    800016e8:	89ae                	mv	s3,a1
    800016ea:	0007871b          	sext.w	a4,a5
    800016ee:	4481                	li	s1,0
    if(cx != '%'){
    800016f0:	02500a13          	li	s4,37
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    800016f4:	0fe00a93          	li	s5,254
    800016f8:	a005                	j	80001718 <sprintf+0x62>
        buf[buf_index++] = cx;
    800016fa:	0017069b          	addw	a3,a4,1
    800016fe:	fad42a23          	sw	a3,-76(s0)
    80001702:	974a                	add	a4,a4,s2
    80001704:	00f70023          	sb	a5,0(a4)
  for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
    80001708:	2485                	addw	s1,s1,1
    8000170a:	009987b3          	add	a5,s3,s1
    8000170e:	0007c783          	lbu	a5,0(a5)
    80001712:	0007871b          	sext.w	a4,a5
    80001716:	c799                	beqz	a5,80001724 <sprintf+0x6e>
    if(cx != '%'){
    80001718:	03470863          	beq	a4,s4,80001748 <sprintf+0x92>
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    8000171c:	fb442703          	lw	a4,-76(s0)
    80001720:	fceadde3          	bge	s5,a4,800016fa <sprintf+0x44>
  }
  
  va_end(ap);
  
  // 确保字符串以null结尾
  if (buf_index < SPRINTF_BUF_MAX) {
    80001724:	fb442503          	lw	a0,-76(s0)
    80001728:	0ff00793          	li	a5,255
    8000172c:	16a7cc63          	blt	a5,a0,800018a4 <sprintf+0x1ee>
    buf[buf_index] = '\0';
    80001730:	992a                	add	s2,s2,a0
    80001732:	00090023          	sb	zero,0(s2)
  } else {
    buf[SPRINTF_BUF_MAX - 1] = '\0'; 
  }
  
  return buf_index; // 返回写入的字符数（不包括null终止符）
    80001736:	60a6                	ld	ra,72(sp)
    80001738:	6406                	ld	s0,64(sp)
    8000173a:	74e2                	ld	s1,56(sp)
    8000173c:	7942                	ld	s2,48(sp)
    8000173e:	79a2                	ld	s3,40(sp)
    80001740:	7a02                	ld	s4,32(sp)
    80001742:	6ae2                	ld	s5,24(sp)
    80001744:	6109                	add	sp,sp,128
    80001746:	8082                	ret
    i++;
    80001748:	2485                	addw	s1,s1,1
    c0 = fmt[i+0] & 0xff;
    8000174a:	009987b3          	add	a5,s3,s1
    8000174e:	0007c703          	lbu	a4,0(a5)
    80001752:	0007079b          	sext.w	a5,a4
    if(c0 == 'd'){
    80001756:	06400693          	li	a3,100
    8000175a:	06d78063          	beq	a5,a3,800017ba <sprintf+0x104>
    } else if(c0 == 'x'){
    8000175e:	07800693          	li	a3,120
    80001762:	06d78b63          	beq	a5,a3,800017d8 <sprintf+0x122>
    } else if(c0 == 'c'){
    80001766:	06300693          	li	a3,99
    8000176a:	08d78763          	beq	a5,a3,800017f8 <sprintf+0x142>
    } else if(c0 == 's'){
    8000176e:	07300693          	li	a3,115
    80001772:	0ad78863          	beq	a5,a3,80001822 <sprintf+0x16c>
    } else if(c0 == '%'){
    80001776:	02500693          	li	a3,37
    8000177a:	10d78563          	beq	a5,a3,80001884 <sprintf+0x1ce>
    } else if(c0 == 0){
    8000177e:	d3dd                	beqz	a5,80001724 <sprintf+0x6e>
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    80001780:	fb442783          	lw	a5,-76(s0)
    80001784:	0fe00693          	li	a3,254
    80001788:	f8f6c0e3          	blt	a3,a5,80001708 <sprintf+0x52>
        buf[buf_index++] = '%';
    8000178c:	0017861b          	addw	a2,a5,1
    80001790:	0006069b          	sext.w	a3,a2
    80001794:	fac42a23          	sw	a2,-76(s0)
    80001798:	00f90633          	add	a2,s2,a5
    8000179c:	02500593          	li	a1,37
    800017a0:	00b60023          	sb	a1,0(a2)
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    800017a4:	0fe00613          	li	a2,254
    800017a8:	f6d640e3          	blt	a2,a3,80001708 <sprintf+0x52>
        buf[buf_index++] = c0;
    800017ac:	2789                	addw	a5,a5,2
    800017ae:	faf42a23          	sw	a5,-76(s0)
    800017b2:	96ca                	add	a3,a3,s2
    800017b4:	00e68023          	sb	a4,0(a3)
    800017b8:	bf81                	j	80001708 <sprintf+0x52>
      print_number_to_buf(va_arg(ap, int), 10, 1, buf, &buf_index);
    800017ba:	fb843783          	ld	a5,-72(s0)
    800017be:	00878713          	add	a4,a5,8
    800017c2:	fae43c23          	sd	a4,-72(s0)
    800017c6:	fb440713          	add	a4,s0,-76
    800017ca:	86ca                	mv	a3,s2
    800017cc:	4605                	li	a2,1
    800017ce:	45a9                	li	a1,10
    800017d0:	4388                	lw	a0,0(a5)
    800017d2:	e4fff0ef          	jal	80001620 <print_number_to_buf>
    800017d6:	bf0d                	j	80001708 <sprintf+0x52>
      print_number_to_buf(va_arg(ap, uint32), 16, 0, buf, &buf_index);
    800017d8:	fb843783          	ld	a5,-72(s0)
    800017dc:	00878713          	add	a4,a5,8
    800017e0:	fae43c23          	sd	a4,-72(s0)
    800017e4:	fb440713          	add	a4,s0,-76
    800017e8:	86ca                	mv	a3,s2
    800017ea:	4601                	li	a2,0
    800017ec:	45c1                	li	a1,16
    800017ee:	0007e503          	lwu	a0,0(a5)
    800017f2:	e2fff0ef          	jal	80001620 <print_number_to_buf>
    800017f6:	bf09                	j	80001708 <sprintf+0x52>
      char c = (char)va_arg(ap, int);
    800017f8:	fb843703          	ld	a4,-72(s0)
    800017fc:	00870793          	add	a5,a4,8
    80001800:	faf43c23          	sd	a5,-72(s0)
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    80001804:	fb442783          	lw	a5,-76(s0)
    80001808:	0fe00693          	li	a3,254
    8000180c:	eef6cee3          	blt	a3,a5,80001708 <sprintf+0x52>
      char c = (char)va_arg(ap, int);
    80001810:	4318                	lw	a4,0(a4)
        buf[buf_index++] = c;
    80001812:	0017869b          	addw	a3,a5,1
    80001816:	fad42a23          	sw	a3,-76(s0)
    8000181a:	97ca                	add	a5,a5,s2
      char c = (char)va_arg(ap, int);
    8000181c:	00e78023          	sb	a4,0(a5)
    80001820:	b5e5                	j	80001708 <sprintf+0x52>
      if((s = va_arg(ap, char*)) == 0)
    80001822:	fb843783          	ld	a5,-72(s0)
    80001826:	00878713          	add	a4,a5,8
    8000182a:	fae43c23          	sd	a4,-72(s0)
    8000182e:	639c                	ld	a5,0(a5)
    80001830:	cf95                	beqz	a5,8000186c <sprintf+0x1b6>
      for(; *s; s++) {
    80001832:	0007c683          	lbu	a3,0(a5)
    80001836:	ec0689e3          	beqz	a3,80001708 <sprintf+0x52>
    8000183a:	fb442703          	lw	a4,-76(s0)
    8000183e:	00e90633          	add	a2,s2,a4
        s = "(null)";
    80001842:	4801                	li	a6,0
        if (buf_index < SPRINTF_BUF_MAX - 1) {
    80001844:	0fe00513          	li	a0,254
    80001848:	4885                	li	a7,1
    8000184a:	02e54863          	blt	a0,a4,8000187a <sprintf+0x1c4>
          buf[buf_index++] = *s;
    8000184e:	0017059b          	addw	a1,a4,1
    80001852:	0005871b          	sext.w	a4,a1
    80001856:	00d60023          	sb	a3,0(a2)
      for(; *s; s++) {
    8000185a:	0785                	add	a5,a5,1
    8000185c:	0007c683          	lbu	a3,0(a5)
    80001860:	0605                	add	a2,a2,1
    80001862:	8846                	mv	a6,a7
    80001864:	f2fd                	bnez	a3,8000184a <sprintf+0x194>
    80001866:	fab42a23          	sw	a1,-76(s0)
    8000186a:	bd79                	j	80001708 <sprintf+0x52>
    8000186c:	02800693          	li	a3,40
        s = "(null)";
    80001870:	00002797          	auipc	a5,0x2
    80001874:	5b878793          	add	a5,a5,1464 # 80003e28 <etext+0xe28>
    80001878:	b7c9                	j	8000183a <sprintf+0x184>
    8000187a:	e80807e3          	beqz	a6,80001708 <sprintf+0x52>
    8000187e:	fae42a23          	sw	a4,-76(s0)
    80001882:	b559                	j	80001708 <sprintf+0x52>
      if (buf_index < SPRINTF_BUF_MAX - 1) {
    80001884:	fb442783          	lw	a5,-76(s0)
    80001888:	0fe00713          	li	a4,254
    8000188c:	e6f74ee3          	blt	a4,a5,80001708 <sprintf+0x52>
        buf[buf_index++] = '%';
    80001890:	0017871b          	addw	a4,a5,1
    80001894:	fae42a23          	sw	a4,-76(s0)
    80001898:	97ca                	add	a5,a5,s2
    8000189a:	02500713          	li	a4,37
    8000189e:	00e78023          	sb	a4,0(a5)
    800018a2:	b59d                	j	80001708 <sprintf+0x52>
    buf[SPRINTF_BUF_MAX - 1] = '\0'; 
    800018a4:	0e090fa3          	sb	zero,255(s2)
    800018a8:	b579                	j	80001736 <sprintf+0x80>

00000000800018aa <console_putc>:
#include "console.h"

// 向控制台输出单个字符
void console_putc(char c)
{
    800018aa:	1141                	add	sp,sp,-16
    800018ac:	e406                	sd	ra,8(sp)
    800018ae:	e022                	sd	s0,0(sp)
    800018b0:	0800                	add	s0,sp,16
  if(c == BACKSPACE){
    uart_putc('\b'); 
    uart_putc(' '); 
    uart_putc('\b');
  } else {
    uart_putc(c);
    800018b2:	c78ff0ef          	jal	80000d2a <uart_putc>
  }
}
    800018b6:	60a2                	ld	ra,8(sp)
    800018b8:	6402                	ld	s0,0(sp)
    800018ba:	0141                	add	sp,sp,16
    800018bc:	8082                	ret

00000000800018be <console_puts>:

// 向控制台输出字符串
void console_puts(char *s) 
{
    800018be:	1101                	add	sp,sp,-32
    800018c0:	ec06                	sd	ra,24(sp)
    800018c2:	e822                	sd	s0,16(sp)
    800018c4:	e426                	sd	s1,8(sp)
    800018c6:	1000                	add	s0,sp,32
    800018c8:	84aa                	mv	s1,a0
    while (*s != '\0') {
    800018ca:	00054503          	lbu	a0,0(a0)
    800018ce:	c519                	beqz	a0,800018dc <console_puts+0x1e>
    uart_putc(c);
    800018d0:	c5aff0ef          	jal	80000d2a <uart_putc>
        console_putc(*s);
        s++;
    800018d4:	0485                	add	s1,s1,1
    while (*s != '\0') {
    800018d6:	0004c503          	lbu	a0,0(s1)
    800018da:	f97d                	bnez	a0,800018d0 <console_puts+0x12>
    }
}
    800018dc:	60e2                	ld	ra,24(sp)
    800018de:	6442                	ld	s0,16(sp)
    800018e0:	64a2                	ld	s1,8(sp)
    800018e2:	6105                	add	sp,sp,32
    800018e4:	8082                	ret

00000000800018e6 <console_init>:

void console_init(void)
{
    800018e6:	1141                	add	sp,sp,-16
    800018e8:	e406                	sd	ra,8(sp)
    800018ea:	e022                	sd	s0,0(sp)
    800018ec:	0800                	add	s0,sp,16
    uart_init();
    800018ee:	c30ff0ef          	jal	80000d1e <uart_init>
    console_puts("Console initialized.\n");
    800018f2:	00003517          	auipc	a0,0x3
    800018f6:	b4650513          	add	a0,a0,-1210 # 80004438 <digits+0x18>
    800018fa:	fc5ff0ef          	jal	800018be <console_puts>
    800018fe:	60a2                	ld	ra,8(sp)
    80001900:	6402                	ld	s0,0(sp)
    80001902:	0141                	add	sp,sp,16
    80001904:	8082                	ret

0000000080001906 <free_page>:
/*
 * 释放一个物理页到空闲链表
 * pa: 要释放的物理页地址（必须页对齐）
 */
void free_page(void *pa)
{
    80001906:	1141                	add	sp,sp,-16
    80001908:	e406                	sd	ra,8(sp)
    8000190a:	e022                	sd	s0,0(sp)
    8000190c:	0800                	add	s0,sp,16
    8000190e:	85aa                	mv	a1,a0
    struct run *r;
    
    // 地址页对齐
    if (((uint64)pa % PGSIZE) != 0) {
    80001910:	03451793          	sll	a5,a0,0x34
    80001914:	eb8d                	bnez	a5,80001946 <free_page+0x40>
        printf("kfree: address not page aligned: 0x%lx\n", (uint64)pa);
        return;
    }
    
    // 地址在有效范围内
    if ((char*)pa < end || (uint64)pa >= PHYSTOP) {
    80001916:	00004797          	auipc	a5,0x4
    8000191a:	7fa78793          	add	a5,a5,2042 # 80006110 <ticks>
    8000191e:	02f56b63          	bltu	a0,a5,80001954 <free_page+0x4e>
    80001922:	47c5                	li	a5,17
    80001924:	07ee                	sll	a5,a5,0x1b
    80001926:	02f57763          	bgeu	a0,a5,80001954 <free_page+0x4e>
    }
    
    // 暂时跳过页面清零，可能会出现数据泄露等问题
    // 将页面加入空闲链表头部
    r = (struct run*)pa;
    r->next = kmem.freelist;
    8000192a:	00003797          	auipc	a5,0x3
    8000192e:	7c678793          	add	a5,a5,1990 # 800050f0 <kmem>
    80001932:	6398                	ld	a4,0(a5)
    80001934:	e118                	sd	a4,0(a0)
    kmem.freelist = r;
    80001936:	e388                	sd	a0,0(a5)
    kmem.free_pages++;
    80001938:	6798                	ld	a4,8(a5)
    8000193a:	0705                	add	a4,a4,1
    8000193c:	e798                	sd	a4,8(a5)
}
    8000193e:	60a2                	ld	ra,8(sp)
    80001940:	6402                	ld	s0,0(sp)
    80001942:	0141                	add	sp,sp,16
    80001944:	8082                	ret
        printf("kfree: address not page aligned: 0x%lx\n", (uint64)pa);
    80001946:	00003517          	auipc	a0,0x3
    8000194a:	b0a50513          	add	a0,a0,-1270 # 80004450 <digits+0x30>
    8000194e:	e46ff0ef          	jal	80000f94 <printf>
        return;
    80001952:	b7f5                	j	8000193e <free_page+0x38>
        printf("kfree: address out of range: 0x%lx\n", (uint64)pa);
    80001954:	00003517          	auipc	a0,0x3
    80001958:	b2450513          	add	a0,a0,-1244 # 80004478 <digits+0x58>
    8000195c:	e38ff0ef          	jal	80000f94 <printf>
        return;
    80001960:	bff9                	j	8000193e <free_page+0x38>

0000000080001962 <freerange>:
{
    80001962:	711d                	add	sp,sp,-96
    80001964:	ec86                	sd	ra,88(sp)
    80001966:	e8a2                	sd	s0,80(sp)
    80001968:	e4a6                	sd	s1,72(sp)
    8000196a:	e0ca                	sd	s2,64(sp)
    8000196c:	fc4e                	sd	s3,56(sp)
    8000196e:	f852                	sd	s4,48(sp)
    80001970:	f456                	sd	s5,40(sp)
    80001972:	f05a                	sd	s6,32(sp)
    80001974:	ec5e                	sd	s7,24(sp)
    80001976:	e862                	sd	s8,16(sp)
    80001978:	e466                	sd	s9,8(sp)
    8000197a:	e06a                	sd	s10,0(sp)
    8000197c:	1080                	add	s0,sp,96
    8000197e:	8aaa                	mv	s5,a0
    80001980:	89ae                	mv	s3,a1
    printf("freerange: start=0x%lx, end=0x%lx\n", (uint64)pa_start, (uint64)pa_end);
    80001982:	862e                	mv	a2,a1
    80001984:	85aa                	mv	a1,a0
    80001986:	00003517          	auipc	a0,0x3
    8000198a:	b1a50513          	add	a0,a0,-1254 # 800044a0 <digits+0x80>
    8000198e:	e06ff0ef          	jal	80000f94 <printf>
    p = (char*)PGROUNDUP((uint64)pa_start);
    80001992:	6485                	lui	s1,0x1
    80001994:	fff48793          	add	a5,s1,-1 # fff <_entry-0x7ffff001>
    80001998:	9abe                	add	s5,s5,a5
    8000199a:	77fd                	lui	a5,0xfffff
    8000199c:	00fafab3          	and	s5,s5,a5
    printf("freerange: aligned start=0x%lx\n", (uint64)p);
    800019a0:	85d6                	mv	a1,s5
    800019a2:	00003517          	auipc	a0,0x3
    800019a6:	b2650513          	add	a0,a0,-1242 # 800044c8 <digits+0xa8>
    800019aa:	deaff0ef          	jal	80000f94 <printf>
    for (; p + PGSIZE <= (char*)pa_end; p += PGSIZE) {
    800019ae:	94d6                	add	s1,s1,s5
    800019b0:	0899ee63          	bltu	s3,s1,80001a4c <freerange+0xea>
    800019b4:	84d6                	mv	s1,s5
    int count = 0;
    800019b6:	4901                	li	s2,0
        if (count % 1000 == 0) {
    800019b8:	3e800c13          	li	s8,1000
            printf("freerange: processing page %d at 0x%lx\n", count, (uint64)p);
    800019bc:	00003c97          	auipc	s9,0x3
    800019c0:	b2cc8c93          	add	s9,s9,-1236 # 800044e8 <digits+0xc8>
        kmem.total_pages++;
    800019c4:	00003a17          	auipc	s4,0x3
    800019c8:	72ca0a13          	add	s4,s4,1836 # 800050f0 <kmem>
    for (; p + PGSIZE <= (char*)pa_end; p += PGSIZE) {
    800019cc:	6b85                	lui	s7,0x1
    800019ce:	6b09                	lui	s6,0x2
    800019d0:	a005                	j	800019f0 <freerange+0x8e>
        free_page(p);
    800019d2:	856a                	mv	a0,s10
    800019d4:	f33ff0ef          	jal	80001906 <free_page>
        kmem.total_pages++;
    800019d8:	010a3783          	ld	a5,16(s4)
    800019dc:	0785                	add	a5,a5,1 # fffffffffffff001 <tests_passed+0xffffffff7fff8ecd>
    800019de:	00fa3823          	sd	a5,16(s4)
        count++;
    800019e2:	2905                	addw	s2,s2,1
    for (; p + PGSIZE <= (char*)pa_end; p += PGSIZE) {
    800019e4:	017487b3          	add	a5,s1,s7
    800019e8:	94da                	add	s1,s1,s6
    800019ea:	0099ed63          	bltu	s3,s1,80001a04 <freerange+0xa2>
    800019ee:	84be                	mv	s1,a5
    800019f0:	8d26                	mv	s10,s1
        if (count % 1000 == 0) {
    800019f2:	038967bb          	remw	a5,s2,s8
    800019f6:	fff1                	bnez	a5,800019d2 <freerange+0x70>
            printf("freerange: processing page %d at 0x%lx\n", count, (uint64)p);
    800019f8:	8626                	mv	a2,s1
    800019fa:	85ca                	mv	a1,s2
    800019fc:	8566                	mv	a0,s9
    800019fe:	d96ff0ef          	jal	80000f94 <printf>
    80001a02:	bfc1                	j	800019d2 <freerange+0x70>
        count++;
    80001a04:	6785                	lui	a5,0x1
    80001a06:	0785                	add	a5,a5,1 # 1001 <_entry-0x7fffefff>
    80001a08:	97d6                	add	a5,a5,s5
    80001a0a:	00198713          	add	a4,s3,1
    80001a0e:	4585                	li	a1,1
    80001a10:	00f76963          	bltu	a4,a5,80001a22 <freerange+0xc0>
    80001a14:	77fd                	lui	a5,0xfffff
    80001a16:	97ce                	add	a5,a5,s3
    80001a18:	415787b3          	sub	a5,a5,s5
    80001a1c:	83b1                	srl	a5,a5,0xc
    80001a1e:	0017859b          	addw	a1,a5,1 # fffffffffffff001 <tests_passed+0xffffffff7fff8ecd>
    80001a22:	2581                	sext.w	a1,a1
    printf("freerange: processed %d pages\n", count);
    80001a24:	00003517          	auipc	a0,0x3
    80001a28:	aec50513          	add	a0,a0,-1300 # 80004510 <digits+0xf0>
    80001a2c:	d68ff0ef          	jal	80000f94 <printf>
}
    80001a30:	60e6                	ld	ra,88(sp)
    80001a32:	6446                	ld	s0,80(sp)
    80001a34:	64a6                	ld	s1,72(sp)
    80001a36:	6906                	ld	s2,64(sp)
    80001a38:	79e2                	ld	s3,56(sp)
    80001a3a:	7a42                	ld	s4,48(sp)
    80001a3c:	7aa2                	ld	s5,40(sp)
    80001a3e:	7b02                	ld	s6,32(sp)
    80001a40:	6be2                	ld	s7,24(sp)
    80001a42:	6c42                	ld	s8,16(sp)
    80001a44:	6ca2                	ld	s9,8(sp)
    80001a46:	6d02                	ld	s10,0(sp)
    80001a48:	6125                	add	sp,sp,96
    80001a4a:	8082                	ret
    int count = 0;
    80001a4c:	4581                	li	a1,0
    80001a4e:	bfd9                	j	80001a24 <freerange+0xc2>

0000000080001a50 <pmm_init>:
{
    80001a50:	1101                	add	sp,sp,-32
    80001a52:	ec06                	sd	ra,24(sp)
    80001a54:	e822                	sd	s0,16(sp)
    80001a56:	e426                	sd	s1,8(sp)
    80001a58:	e04a                	sd	s2,0(sp)
    80001a5a:	1000                	add	s0,sp,32
    kmem.freelist = 0;
    80001a5c:	00003497          	auipc	s1,0x3
    80001a60:	69448493          	add	s1,s1,1684 # 800050f0 <kmem>
    80001a64:	0004b023          	sd	zero,0(s1)
    kmem.free_pages = 0;
    80001a68:	0004b423          	sd	zero,8(s1)
    kmem.total_pages = 0;
    80001a6c:	0004b823          	sd	zero,16(s1)
    printf("Physical memory allocator initializing...\n");
    80001a70:	00003517          	auipc	a0,0x3
    80001a74:	ac050513          	add	a0,a0,-1344 # 80004530 <digits+0x110>
    80001a78:	d1cff0ef          	jal	80000f94 <printf>
    printf("Kernel end: 0x%lx\n", (uint64)end);
    80001a7c:	00004597          	auipc	a1,0x4
    80001a80:	69458593          	add	a1,a1,1684 # 80006110 <ticks>
    80001a84:	00003517          	auipc	a0,0x3
    80001a88:	adc50513          	add	a0,a0,-1316 # 80004560 <digits+0x140>
    80001a8c:	d08ff0ef          	jal	80000f94 <printf>
    printf("Physical memory top: 0x%lx\n", PHYSTOP);
    80001a90:	4945                	li	s2,17
    80001a92:	01b91593          	sll	a1,s2,0x1b
    80001a96:	00003517          	auipc	a0,0x3
    80001a9a:	ae250513          	add	a0,a0,-1310 # 80004578 <digits+0x158>
    80001a9e:	cf6ff0ef          	jal	80000f94 <printf>
    printf("About to call freerange...\n");
    80001aa2:	00003517          	auipc	a0,0x3
    80001aa6:	af650513          	add	a0,a0,-1290 # 80004598 <digits+0x178>
    80001aaa:	ceaff0ef          	jal	80000f94 <printf>
    freerange(end, (void*)PHYSTOP);
    80001aae:	01b91593          	sll	a1,s2,0x1b
    80001ab2:	00004517          	auipc	a0,0x4
    80001ab6:	65e50513          	add	a0,a0,1630 # 80006110 <ticks>
    80001aba:	ea9ff0ef          	jal	80001962 <freerange>
    printf("freerange completed.\n");
    80001abe:	00003517          	auipc	a0,0x3
    80001ac2:	afa50513          	add	a0,a0,-1286 # 800045b8 <digits+0x198>
    80001ac6:	cceff0ef          	jal	80000f94 <printf>
    printf("Physical memory allocator initialized.\n");
    80001aca:	00003517          	auipc	a0,0x3
    80001ace:	b0650513          	add	a0,a0,-1274 # 800045d0 <digits+0x1b0>
    80001ad2:	cc2ff0ef          	jal	80000f94 <printf>
    printf("Total pages: %ld, Free pages: %ld\n", kmem.total_pages, kmem.free_pages);
    80001ad6:	6490                	ld	a2,8(s1)
    80001ad8:	688c                	ld	a1,16(s1)
    80001ada:	00003517          	auipc	a0,0x3
    80001ade:	b1e50513          	add	a0,a0,-1250 # 800045f8 <digits+0x1d8>
    80001ae2:	cb2ff0ef          	jal	80000f94 <printf>
}
    80001ae6:	60e2                	ld	ra,24(sp)
    80001ae8:	6442                	ld	s0,16(sp)
    80001aea:	64a2                	ld	s1,8(sp)
    80001aec:	6902                	ld	s2,0(sp)
    80001aee:	6105                	add	sp,sp,32
    80001af0:	8082                	ret

0000000080001af2 <alloc_page>:
/*
 * 分配一个物理页
 * 返回: 分配的页面地址，失败时返回0
 */
void* alloc_page(void)
{
    80001af2:	1141                	add	sp,sp,-16
    80001af4:	e422                	sd	s0,8(sp)
    80001af6:	0800                	add	s0,sp,16
    struct run *r;
    
    // 从空闲链表头部取出一页
    r = kmem.freelist;
    80001af8:	00003517          	auipc	a0,0x3
    80001afc:	5f853503          	ld	a0,1528(a0) # 800050f0 <kmem>
    if (r) {
    80001b00:	c11d                	beqz	a0,80001b26 <alloc_page+0x34>
        kmem.freelist = r->next;
    80001b02:	6118                	ld	a4,0(a0)
    80001b04:	00003797          	auipc	a5,0x3
    80001b08:	5ec78793          	add	a5,a5,1516 # 800050f0 <kmem>
    80001b0c:	e398                	sd	a4,0(a5)
        kmem.free_pages--;
    80001b0e:	6798                	ld	a4,8(a5)
    80001b10:	177d                	add	a4,a4,-1
    80001b12:	e798                	sd	a4,8(a5)
    for (uint64 i = 0; i < n; i++) {
    80001b14:	87aa                	mv	a5,a0
    80001b16:	6705                	lui	a4,0x1
    80001b18:	972a                	add	a4,a4,a0
        cdst[i] = c;
    80001b1a:	4695                	li	a3,5
    80001b1c:	00d78023          	sb	a3,0(a5)
    for (uint64 i = 0; i < n; i++) {
    80001b20:	0785                	add	a5,a5,1
    80001b22:	fee79de3          	bne	a5,a4,80001b1c <alloc_page+0x2a>
        // 用垃圾数据填充页面，帮助发现未初始化使用问题
        memset((char*)r, 5, PGSIZE);
    }
    
    return (void*)r;
}
    80001b26:	6422                	ld	s0,8(sp)
    80001b28:	0141                	add	sp,sp,16
    80001b2a:	8082                	ret

0000000080001b2c <get_free_pages>:

/*
 * 获取空闲页数量
 */
uint64 get_free_pages(void)
{
    80001b2c:	1141                	add	sp,sp,-16
    80001b2e:	e422                	sd	s0,8(sp)
    80001b30:	0800                	add	s0,sp,16
    return kmem.free_pages;
}
    80001b32:	00003517          	auipc	a0,0x3
    80001b36:	5c653503          	ld	a0,1478(a0) # 800050f8 <kmem+0x8>
    80001b3a:	6422                	ld	s0,8(sp)
    80001b3c:	0141                	add	sp,sp,16
    80001b3e:	8082                	ret

0000000080001b40 <get_total_pages>:

/*
 * 获取总页数量
 */
uint64 get_total_pages(void)
{
    80001b40:	1141                	add	sp,sp,-16
    80001b42:	e422                	sd	s0,8(sp)
    80001b44:	0800                	add	s0,sp,16
    return kmem.total_pages;
}
    80001b46:	00003517          	auipc	a0,0x3
    80001b4a:	5ba53503          	ld	a0,1466(a0) # 80005100 <kmem+0x10>
    80001b4e:	6422                	ld	s0,8(sp)
    80001b50:	0141                	add	sp,sp,16
    80001b52:	8082                	ret

0000000080001b54 <print_kmem_stats>:

/*
 * 打印内存分配器状态,用于调试
 */
void print_kmem_stats(void)
{
    80001b54:	1101                	add	sp,sp,-32
    80001b56:	ec06                	sd	ra,24(sp)
    80001b58:	e822                	sd	s0,16(sp)
    80001b5a:	e426                	sd	s1,8(sp)
    80001b5c:	1000                	add	s0,sp,32
    printf("Memory allocator statistics:\n");
    80001b5e:	00003517          	auipc	a0,0x3
    80001b62:	ac250513          	add	a0,a0,-1342 # 80004620 <digits+0x200>
    80001b66:	c2eff0ef          	jal	80000f94 <printf>
    printf("  Total pages: %ld (%ld MB)\n", 
    80001b6a:	00003497          	auipc	s1,0x3
    80001b6e:	58648493          	add	s1,s1,1414 # 800050f0 <kmem>
    80001b72:	688c                	ld	a1,16(s1)
           kmem.total_pages, (kmem.total_pages * PGSIZE) / (1024 * 1024));
    80001b74:	00c59613          	sll	a2,a1,0xc
    printf("  Total pages: %ld (%ld MB)\n", 
    80001b78:	8251                	srl	a2,a2,0x14
    80001b7a:	00003517          	auipc	a0,0x3
    80001b7e:	ac650513          	add	a0,a0,-1338 # 80004640 <digits+0x220>
    80001b82:	c12ff0ef          	jal	80000f94 <printf>
    printf("  Free pages: %ld (%ld MB)\n", 
    80001b86:	648c                	ld	a1,8(s1)
           kmem.free_pages, (kmem.free_pages * PGSIZE) / (1024 * 1024));
    80001b88:	00c59613          	sll	a2,a1,0xc
    printf("  Free pages: %ld (%ld MB)\n", 
    80001b8c:	8251                	srl	a2,a2,0x14
    80001b8e:	00003517          	auipc	a0,0x3
    80001b92:	ad250513          	add	a0,a0,-1326 # 80004660 <digits+0x240>
    80001b96:	bfeff0ef          	jal	80000f94 <printf>
    printf("  Used pages: %ld (%ld MB)\n", 
    80001b9a:	688c                	ld	a1,16(s1)
    80001b9c:	649c                	ld	a5,8(s1)
    80001b9e:	8d9d                	sub	a1,a1,a5
           kmem.total_pages - kmem.free_pages, 
           ((kmem.total_pages - kmem.free_pages) * PGSIZE) / (1024 * 1024));
    80001ba0:	00c59613          	sll	a2,a1,0xc
    printf("  Used pages: %ld (%ld MB)\n", 
    80001ba4:	8251                	srl	a2,a2,0x14
    80001ba6:	00003517          	auipc	a0,0x3
    80001baa:	ada50513          	add	a0,a0,-1318 # 80004680 <digits+0x260>
    80001bae:	be6ff0ef          	jal	80000f94 <printf>
    printf("  Page size: %d bytes\n", PGSIZE);
    80001bb2:	6585                	lui	a1,0x1
    80001bb4:	00003517          	auipc	a0,0x3
    80001bb8:	aec50513          	add	a0,a0,-1300 # 800046a0 <digits+0x280>
    80001bbc:	bd8ff0ef          	jal	80000f94 <printf>
    80001bc0:	60e2                	ld	ra,24(sp)
    80001bc2:	6442                	ld	s0,16(sp)
    80001bc4:	64a2                	ld	s1,8(sp)
    80001bc6:	6105                	add	sp,sp,32
    80001bc8:	8082                	ret

0000000080001bca <freewalk>:

/*
 * 递归释放页表
 */
static void freewalk(pagetable_t pagetable, int level)
{
    80001bca:	7139                	add	sp,sp,-64
    80001bcc:	fc06                	sd	ra,56(sp)
    80001bce:	f822                	sd	s0,48(sp)
    80001bd0:	f426                	sd	s1,40(sp)
    80001bd2:	f04a                	sd	s2,32(sp)
    80001bd4:	ec4e                	sd	s3,24(sp)
    80001bd6:	e852                	sd	s4,16(sp)
    80001bd8:	e456                	sd	s5,8(sp)
    80001bda:	0080                	add	s0,sp,64
    80001bdc:	8aaa                	mv	s5,a0
    80001bde:	8a2e                	mv	s4,a1
    // 遍历页表的所有条目
    for (int i = 0; i < 512; i++) {
    80001be0:	84aa                	mv	s1,a0
    80001be2:	6905                	lui	s2,0x1
    80001be4:	992a                	add	s2,s2,a0
    80001be6:	a021                	j	80001bee <freewalk+0x24>
    80001be8:	04a1                	add	s1,s1,8
    80001bea:	03248263          	beq	s1,s2,80001c0e <freewalk+0x44>
        pte_t pte = pagetable[i];
    80001bee:	609c                	ld	a5,0(s1)
        if (pte & PTE_V) {
    80001bf0:	0017f713          	and	a4,a5,1
    80001bf4:	db75                	beqz	a4,80001be8 <freewalk+0x1e>
            if (level > 0) {
    80001bf6:	ff4059e3          	blez	s4,80001be8 <freewalk+0x1e>
                // 中间级页表，递归释放
                uint64 child = PTE2PA(pte);
    80001bfa:	83a9                	srl	a5,a5,0xa
                freewalk((pagetable_t)child, level - 1);
    80001bfc:	fffa059b          	addw	a1,s4,-1
    80001c00:	00c79513          	sll	a0,a5,0xc
    80001c04:	fc7ff0ef          	jal	80001bca <freewalk>
                pagetable[i] = 0;
    80001c08:	0004b023          	sd	zero,0(s1)
    80001c0c:	bff1                	j	80001be8 <freewalk+0x1e>
            }
        }
    }
    free_page((void*)pagetable);
    80001c0e:	8556                	mv	a0,s5
    80001c10:	cf7ff0ef          	jal	80001906 <free_page>
}
    80001c14:	70e2                	ld	ra,56(sp)
    80001c16:	7442                	ld	s0,48(sp)
    80001c18:	74a2                	ld	s1,40(sp)
    80001c1a:	7902                	ld	s2,32(sp)
    80001c1c:	69e2                	ld	s3,24(sp)
    80001c1e:	6a42                	ld	s4,16(sp)
    80001c20:	6aa2                	ld	s5,8(sp)
    80001c22:	6121                	add	sp,sp,64
    80001c24:	8082                	ret

0000000080001c26 <create_pagetable>:
{
    80001c26:	1141                	add	sp,sp,-16
    80001c28:	e406                	sd	ra,8(sp)
    80001c2a:	e022                	sd	s0,0(sp)
    80001c2c:	0800                	add	s0,sp,16
    pagetable = (pagetable_t)alloc_page();
    80001c2e:	ec5ff0ef          	jal	80001af2 <alloc_page>
    if (pagetable == 0) {
    80001c32:	c909                	beqz	a0,80001c44 <create_pagetable+0x1e>
    80001c34:	87aa                	mv	a5,a0
    80001c36:	6705                	lui	a4,0x1
    80001c38:	972a                	add	a4,a4,a0
        cdst[i] = c;
    80001c3a:	00078023          	sb	zero,0(a5)
    for (uint64 i = 0; i < n; i++) {
    80001c3e:	0785                	add	a5,a5,1
    80001c40:	fee79de3          	bne	a5,a4,80001c3a <create_pagetable+0x14>
}
    80001c44:	60a2                	ld	ra,8(sp)
    80001c46:	6402                	ld	s0,0(sp)
    80001c48:	0141                	add	sp,sp,16
    80001c4a:	8082                	ret

0000000080001c4c <walk>:
{
    80001c4c:	7139                	add	sp,sp,-64
    80001c4e:	fc06                	sd	ra,56(sp)
    80001c50:	f822                	sd	s0,48(sp)
    80001c52:	f426                	sd	s1,40(sp)
    80001c54:	f04a                	sd	s2,32(sp)
    80001c56:	ec4e                	sd	s3,24(sp)
    80001c58:	e852                	sd	s4,16(sp)
    80001c5a:	e456                	sd	s5,8(sp)
    80001c5c:	0080                	add	s0,sp,64
    80001c5e:	892e                	mv	s2,a1
    80001c60:	8a32                	mv	s4,a2
    if (va >= MAXVA) {
    80001c62:	57fd                	li	a5,-1
    80001c64:	83e9                	srl	a5,a5,0x1a
    80001c66:	49f9                	li	s3,30
    for (int level = 2; level > 0; level--) {
    80001c68:	4ab1                	li	s5,12
    if (va >= MAXVA) {
    80001c6a:	00b7ff63          	bgeu	a5,a1,80001c88 <walk+0x3c>
        printf("walk: virtual address too large: 0x%lx\n", va);
    80001c6e:	00003517          	auipc	a0,0x3
    80001c72:	a4a50513          	add	a0,a0,-1462 # 800046b8 <digits+0x298>
    80001c76:	b1eff0ef          	jal	80000f94 <printf>
        return 0;
    80001c7a:	4501                	li	a0,0
    80001c7c:	a899                	j	80001cd2 <walk+0x86>
            pagetable = (pagetable_t)PTE2PA(*pte);
    80001c7e:	8129                	srl	a0,a0,0xa
    80001c80:	0532                	sll	a0,a0,0xc
    for (int level = 2; level > 0; level--) {
    80001c82:	39dd                	addw	s3,s3,-9
    80001c84:	05598163          	beq	s3,s5,80001cc6 <walk+0x7a>
        pte_t *pte = &pagetable[PX(level, va)];
    80001c88:	013954b3          	srl	s1,s2,s3
    80001c8c:	1ff4f493          	and	s1,s1,511
    80001c90:	048e                	sll	s1,s1,0x3
    80001c92:	94aa                	add	s1,s1,a0
        if (*pte & PTE_V) {
    80001c94:	6088                	ld	a0,0(s1)
    80001c96:	00157793          	and	a5,a0,1
    80001c9a:	f3f5                	bnez	a5,80001c7e <walk+0x32>
            if (!alloc) {
    80001c9c:	040a0463          	beqz	s4,80001ce4 <walk+0x98>
            pagetable = (pagetable_t)alloc_page();
    80001ca0:	e53ff0ef          	jal	80001af2 <alloc_page>
            if (pagetable == 0) {
    80001ca4:	c51d                	beqz	a0,80001cd2 <walk+0x86>
    80001ca6:	86aa                	mv	a3,a0
    80001ca8:	6705                	lui	a4,0x1
    80001caa:	972a                	add	a4,a4,a0
    80001cac:	87aa                	mv	a5,a0
        cdst[i] = c;
    80001cae:	00078023          	sb	zero,0(a5)
    for (uint64 i = 0; i < n; i++) {
    80001cb2:	0785                	add	a5,a5,1
    80001cb4:	fee79de3          	bne	a5,a4,80001cae <walk+0x62>
            *pte = PA2PTE(pagetable) | PTE_V;
    80001cb8:	00c6d793          	srl	a5,a3,0xc
    80001cbc:	07aa                	sll	a5,a5,0xa
    80001cbe:	0017e793          	or	a5,a5,1
    80001cc2:	e09c                	sd	a5,0(s1)
    80001cc4:	bf7d                	j	80001c82 <walk+0x36>
    return &pagetable[PX(0, va)];
    80001cc6:	00c95913          	srl	s2,s2,0xc
    80001cca:	1ff97913          	and	s2,s2,511
    80001cce:	090e                	sll	s2,s2,0x3
    80001cd0:	954a                	add	a0,a0,s2
}
    80001cd2:	70e2                	ld	ra,56(sp)
    80001cd4:	7442                	ld	s0,48(sp)
    80001cd6:	74a2                	ld	s1,40(sp)
    80001cd8:	7902                	ld	s2,32(sp)
    80001cda:	69e2                	ld	s3,24(sp)
    80001cdc:	6a42                	ld	s4,16(sp)
    80001cde:	6aa2                	ld	s5,8(sp)
    80001ce0:	6121                	add	sp,sp,64
    80001ce2:	8082                	ret
                return 0;  // 不分配新页表，返回失败
    80001ce4:	4501                	li	a0,0
    80001ce6:	b7f5                	j	80001cd2 <walk+0x86>

0000000080001ce8 <walkaddr>:
    if (va >= MAXVA) {
    80001ce8:	57fd                	li	a5,-1
    80001cea:	83e9                	srl	a5,a5,0x1a
    80001cec:	00b7f463          	bgeu	a5,a1,80001cf4 <walkaddr+0xc>
        return 0;
    80001cf0:	4501                	li	a0,0
}
    80001cf2:	8082                	ret
{
    80001cf4:	1141                	add	sp,sp,-16
    80001cf6:	e406                	sd	ra,8(sp)
    80001cf8:	e022                	sd	s0,0(sp)
    80001cfa:	0800                	add	s0,sp,16
    pte = walk(pagetable, va, 0);
    80001cfc:	4601                	li	a2,0
    80001cfe:	f4fff0ef          	jal	80001c4c <walk>
    if (pte == 0) {
    80001d02:	cd01                	beqz	a0,80001d1a <walkaddr+0x32>
    if ((*pte & PTE_V) == 0) {
    80001d04:	611c                	ld	a5,0(a0)
    80001d06:	0017f513          	and	a0,a5,1
    80001d0a:	c501                	beqz	a0,80001d12 <walkaddr+0x2a>
    pa = PTE2PA(*pte);
    80001d0c:	83a9                	srl	a5,a5,0xa
    80001d0e:	00c79513          	sll	a0,a5,0xc
}
    80001d12:	60a2                	ld	ra,8(sp)
    80001d14:	6402                	ld	s0,0(sp)
    80001d16:	0141                	add	sp,sp,16
    80001d18:	8082                	ret
        return 0;
    80001d1a:	4501                	li	a0,0
    80001d1c:	bfdd                	j	80001d12 <walkaddr+0x2a>

0000000080001d1e <map_pages>:
{
    80001d1e:	715d                	add	sp,sp,-80
    80001d20:	e486                	sd	ra,72(sp)
    80001d22:	e0a2                	sd	s0,64(sp)
    80001d24:	fc26                	sd	s1,56(sp)
    80001d26:	f84a                	sd	s2,48(sp)
    80001d28:	f44e                	sd	s3,40(sp)
    80001d2a:	f052                	sd	s4,32(sp)
    80001d2c:	ec56                	sd	s5,24(sp)
    80001d2e:	e85a                	sd	s6,16(sp)
    80001d30:	e45e                	sd	s7,8(sp)
    80001d32:	0880                	add	s0,sp,80
    if ((va % PGSIZE) != 0) {
    80001d34:	03459793          	sll	a5,a1,0x34
    80001d38:	e7a9                	bnez	a5,80001d82 <map_pages+0x64>
    80001d3a:	8aaa                	mv	s5,a0
    80001d3c:	8b3a                	mv	s6,a4
    if ((size % PGSIZE) != 0) {
    80001d3e:	03461793          	sll	a5,a2,0x34
    80001d42:	eba1                	bnez	a5,80001d92 <map_pages+0x74>
    if (size == 0) {
    80001d44:	c225                	beqz	a2,80001da4 <map_pages+0x86>
    last = va + size - PGSIZE;
    80001d46:	77fd                	lui	a5,0xfffff
    80001d48:	963e                	add	a2,a2,a5
    80001d4a:	00b609b3          	add	s3,a2,a1
    a = va;
    80001d4e:	892e                	mv	s2,a1
    80001d50:	40b68a33          	sub	s4,a3,a1
        a += PGSIZE;
    80001d54:	6b85                	lui	s7,0x1
    80001d56:	014904b3          	add	s1,s2,s4
        pte = walk(pagetable, a, 1);
    80001d5a:	4605                	li	a2,1
    80001d5c:	85ca                	mv	a1,s2
    80001d5e:	8556                	mv	a0,s5
    80001d60:	eedff0ef          	jal	80001c4c <walk>
        if (pte == 0) {
    80001d64:	c921                	beqz	a0,80001db4 <map_pages+0x96>
        if (*pte & PTE_V) {
    80001d66:	611c                	ld	a5,0(a0)
    80001d68:	8b85                	and	a5,a5,1
    80001d6a:	eba5                	bnez	a5,80001dda <map_pages+0xbc>
        *pte = PA2PTE(pa) | perm | PTE_V;
    80001d6c:	80b1                	srl	s1,s1,0xc
    80001d6e:	04aa                	sll	s1,s1,0xa
    80001d70:	0164e4b3          	or	s1,s1,s6
    80001d74:	0014e493          	or	s1,s1,1
    80001d78:	e104                	sd	s1,0(a0)
        if (a == last) {
    80001d7a:	07390963          	beq	s2,s3,80001dec <map_pages+0xce>
        a += PGSIZE;
    80001d7e:	995e                	add	s2,s2,s7
        pte = walk(pagetable, a, 1);
    80001d80:	bfd9                	j	80001d56 <map_pages+0x38>
        printf("map_pages: va not aligned: 0x%lx\n", va);
    80001d82:	00003517          	auipc	a0,0x3
    80001d86:	95e50513          	add	a0,a0,-1698 # 800046e0 <digits+0x2c0>
    80001d8a:	a0aff0ef          	jal	80000f94 <printf>
        return -1;
    80001d8e:	557d                	li	a0,-1
    80001d90:	a815                	j	80001dc4 <map_pages+0xa6>
        printf("map_pages: size not aligned: %ld\n", size);
    80001d92:	85b2                	mv	a1,a2
    80001d94:	00003517          	auipc	a0,0x3
    80001d98:	97450513          	add	a0,a0,-1676 # 80004708 <digits+0x2e8>
    80001d9c:	9f8ff0ef          	jal	80000f94 <printf>
        return -1;
    80001da0:	557d                	li	a0,-1
    80001da2:	a00d                	j	80001dc4 <map_pages+0xa6>
        printf("map_pages: size is zero\n");
    80001da4:	00003517          	auipc	a0,0x3
    80001da8:	98c50513          	add	a0,a0,-1652 # 80004730 <digits+0x310>
    80001dac:	9e8ff0ef          	jal	80000f94 <printf>
        return -1;
    80001db0:	557d                	li	a0,-1
    80001db2:	a809                	j	80001dc4 <map_pages+0xa6>
            printf("map_pages: walk failed for va 0x%lx\n", a);
    80001db4:	85ca                	mv	a1,s2
    80001db6:	00003517          	auipc	a0,0x3
    80001dba:	99a50513          	add	a0,a0,-1638 # 80004750 <digits+0x330>
    80001dbe:	9d6ff0ef          	jal	80000f94 <printf>
            return -1;
    80001dc2:	557d                	li	a0,-1
}
    80001dc4:	60a6                	ld	ra,72(sp)
    80001dc6:	6406                	ld	s0,64(sp)
    80001dc8:	74e2                	ld	s1,56(sp)
    80001dca:	7942                	ld	s2,48(sp)
    80001dcc:	79a2                	ld	s3,40(sp)
    80001dce:	7a02                	ld	s4,32(sp)
    80001dd0:	6ae2                	ld	s5,24(sp)
    80001dd2:	6b42                	ld	s6,16(sp)
    80001dd4:	6ba2                	ld	s7,8(sp)
    80001dd6:	6161                	add	sp,sp,80
    80001dd8:	8082                	ret
            printf("map_pages: remap attempt at va 0x%lx\n", a);
    80001dda:	85ca                	mv	a1,s2
    80001ddc:	00003517          	auipc	a0,0x3
    80001de0:	99c50513          	add	a0,a0,-1636 # 80004778 <digits+0x358>
    80001de4:	9b0ff0ef          	jal	80000f94 <printf>
            return -1;
    80001de8:	557d                	li	a0,-1
    80001dea:	bfe9                	j	80001dc4 <map_pages+0xa6>
    return 0;
    80001dec:	4501                	li	a0,0
    80001dee:	bfd9                	j	80001dc4 <map_pages+0xa6>

0000000080001df0 <kvmmap>:
{
    80001df0:	7179                	add	sp,sp,-48
    80001df2:	f406                	sd	ra,40(sp)
    80001df4:	f022                	sd	s0,32(sp)
    80001df6:	ec26                	sd	s1,24(sp)
    80001df8:	e84a                	sd	s2,16(sp)
    80001dfa:	e44e                	sd	s3,8(sp)
    80001dfc:	1800                	add	s0,sp,48
    80001dfe:	89ae                	mv	s3,a1
    80001e00:	84b2                	mv	s1,a2
    80001e02:	8936                	mv	s2,a3
    if (map_pages(kpgtbl, va, sz, pa, perm) != 0) {
    80001e04:	86b2                	mv	a3,a2
    80001e06:	864a                	mv	a2,s2
    80001e08:	f17ff0ef          	jal	80001d1e <map_pages>
    80001e0c:	e901                	bnez	a0,80001e1c <kvmmap+0x2c>
}
    80001e0e:	70a2                	ld	ra,40(sp)
    80001e10:	7402                	ld	s0,32(sp)
    80001e12:	64e2                	ld	s1,24(sp)
    80001e14:	6942                	ld	s2,16(sp)
    80001e16:	69a2                	ld	s3,8(sp)
    80001e18:	6145                	add	sp,sp,48
    80001e1a:	8082                	ret
        printf("kvmmap failed: va=0x%lx, pa=0x%lx, sz=%ld\n", va, pa, sz);
    80001e1c:	86ca                	mv	a3,s2
    80001e1e:	8626                	mv	a2,s1
    80001e20:	85ce                	mv	a1,s3
    80001e22:	00003517          	auipc	a0,0x3
    80001e26:	97e50513          	add	a0,a0,-1666 # 800047a0 <digits+0x380>
    80001e2a:	96aff0ef          	jal	80000f94 <printf>
}
    80001e2e:	b7c5                	j	80001e0e <kvmmap+0x1e>

0000000080001e30 <kvminit>:
{
    80001e30:	1101                	add	sp,sp,-32
    80001e32:	ec06                	sd	ra,24(sp)
    80001e34:	e822                	sd	s0,16(sp)
    80001e36:	e426                	sd	s1,8(sp)
    80001e38:	e04a                	sd	s2,0(sp)
    80001e3a:	1000                	add	s0,sp,32
    printf("Initializing kernel virtual memory...\n");
    80001e3c:	00003517          	auipc	a0,0x3
    80001e40:	99450513          	add	a0,a0,-1644 # 800047d0 <digits+0x3b0>
    80001e44:	950ff0ef          	jal	80000f94 <printf>
    kpgtbl = create_pagetable();
    80001e48:	ddfff0ef          	jal	80001c26 <create_pagetable>
    if (kpgtbl == 0) {
    80001e4c:	c559                	beqz	a0,80001eda <kvminit+0xaa>
    80001e4e:	84aa                	mv	s1,a0
    kvmmap(kpgtbl, UART0, UART0, PGSIZE, PTE_R | PTE_W);
    80001e50:	4719                	li	a4,6
    80001e52:	6685                	lui	a3,0x1
    80001e54:	10000637          	lui	a2,0x10000
    80001e58:	100005b7          	lui	a1,0x10000
    80001e5c:	f95ff0ef          	jal	80001df0 <kvmmap>
    kvmmap(kpgtbl, VIRTIO0, VIRTIO0, PGSIZE, PTE_R | PTE_W);
    80001e60:	4719                	li	a4,6
    80001e62:	6685                	lui	a3,0x1
    80001e64:	10001637          	lui	a2,0x10001
    80001e68:	100015b7          	lui	a1,0x10001
    80001e6c:	8526                	mv	a0,s1
    80001e6e:	f83ff0ef          	jal	80001df0 <kvmmap>
    kvmmap(kpgtbl, PLIC, PLIC, 0x4000000, PTE_R | PTE_W);
    80001e72:	4719                	li	a4,6
    80001e74:	040006b7          	lui	a3,0x4000
    80001e78:	0c000637          	lui	a2,0xc000
    80001e7c:	0c0005b7          	lui	a1,0xc000
    80001e80:	8526                	mv	a0,s1
    80001e82:	f6fff0ef          	jal	80001df0 <kvmmap>
    kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext - KERNBASE, PTE_R | PTE_X);
    80001e86:	00001917          	auipc	s2,0x1
    80001e8a:	17a90913          	add	s2,s2,378 # 80003000 <etext>
    80001e8e:	4729                	li	a4,10
    80001e90:	80001697          	auipc	a3,0x80001
    80001e94:	17068693          	add	a3,a3,368 # 3000 <_entry-0x7fffd000>
    80001e98:	4605                	li	a2,1
    80001e9a:	067e                	sll	a2,a2,0x1f
    80001e9c:	85b2                	mv	a1,a2
    80001e9e:	8526                	mv	a0,s1
    80001ea0:	f51ff0ef          	jal	80001df0 <kvmmap>
    kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP - (uint64)etext, PTE_R | PTE_W);
    80001ea4:	4719                	li	a4,6
    80001ea6:	46c5                	li	a3,17
    80001ea8:	06ee                	sll	a3,a3,0x1b
    80001eaa:	412686b3          	sub	a3,a3,s2
    80001eae:	864a                	mv	a2,s2
    80001eb0:	85ca                	mv	a1,s2
    80001eb2:	8526                	mv	a0,s1
    80001eb4:	f3dff0ef          	jal	80001df0 <kvmmap>
    kernel_pagetable = kvmmake();
    80001eb8:	00004797          	auipc	a5,0x4
    80001ebc:	2697b823          	sd	s1,624(a5) # 80006128 <kernel_pagetable>
    printf("Kernel page table created at 0x%lx\n", (uint64)kernel_pagetable);
    80001ec0:	85a6                	mv	a1,s1
    80001ec2:	00003517          	auipc	a0,0x3
    80001ec6:	99650513          	add	a0,a0,-1642 # 80004858 <digits+0x438>
    80001eca:	8caff0ef          	jal	80000f94 <printf>
}
    80001ece:	60e2                	ld	ra,24(sp)
    80001ed0:	6442                	ld	s0,16(sp)
    80001ed2:	64a2                	ld	s1,8(sp)
    80001ed4:	6902                	ld	s2,0(sp)
    80001ed6:	6105                	add	sp,sp,32
    80001ed8:	8082                	ret
        printf("kvmmake: failed to allocate kernel page table\n");
    80001eda:	00003517          	auipc	a0,0x3
    80001ede:	91e50513          	add	a0,a0,-1762 # 800047f8 <digits+0x3d8>
    80001ee2:	8b2ff0ef          	jal	80000f94 <printf>
    kernel_pagetable = kvmmake();
    80001ee6:	00004797          	auipc	a5,0x4
    80001eea:	2407b123          	sd	zero,578(a5) # 80006128 <kernel_pagetable>
        printf("kvminit: failed to create kernel page table\n");
    80001eee:	00003517          	auipc	a0,0x3
    80001ef2:	93a50513          	add	a0,a0,-1734 # 80004828 <digits+0x408>
    80001ef6:	89eff0ef          	jal	80000f94 <printf>
        return;
    80001efa:	bfd1                	j	80001ece <kvminit+0x9e>

0000000080001efc <kvminithart>:
{
    80001efc:	1141                	add	sp,sp,-16
    80001efe:	e406                	sd	ra,8(sp)
    80001f00:	e022                	sd	s0,0(sp)
    80001f02:	0800                	add	s0,sp,16
    w_satp(MAKE_SATP(kernel_pagetable));
    80001f04:	00004797          	auipc	a5,0x4
    80001f08:	2247b783          	ld	a5,548(a5) # 80006128 <kernel_pagetable>
    80001f0c:	83b1                	srl	a5,a5,0xc
    80001f0e:	577d                	li	a4,-1
    80001f10:	177e                	sll	a4,a4,0x3f
    80001f12:	8fd9                	or	a5,a5,a4
#define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64_t)pagetable) >> 12))

// 读写SATP寄存器
static inline void w_satp(uint64_t x)
{
    asm volatile("csrw satp, %0" : : "r" (x));
    80001f14:	18079073          	csrw	satp,a5

// 刷新TLB
static inline void sfence_vma()
{
    // 刷新所有TLB条目
    asm volatile("sfence.vma zero, zero");
    80001f18:	12000073          	sfence.vma
    printf("Kernel page table activated on hart\n");
    80001f1c:	00003517          	auipc	a0,0x3
    80001f20:	96450513          	add	a0,a0,-1692 # 80004880 <digits+0x460>
    80001f24:	870ff0ef          	jal	80000f94 <printf>
}
    80001f28:	60a2                	ld	ra,8(sp)
    80001f2a:	6402                	ld	s0,0(sp)
    80001f2c:	0141                	add	sp,sp,16
    80001f2e:	8082                	ret

0000000080001f30 <uvmcreate>:
{
    80001f30:	1141                	add	sp,sp,-16
    80001f32:	e406                	sd	ra,8(sp)
    80001f34:	e022                	sd	s0,0(sp)
    80001f36:	0800                	add	s0,sp,16
    pagetable = create_pagetable();
    80001f38:	cefff0ef          	jal	80001c26 <create_pagetable>
}
    80001f3c:	60a2                	ld	ra,8(sp)
    80001f3e:	6402                	ld	s0,0(sp)
    80001f40:	0141                	add	sp,sp,16
    80001f42:	8082                	ret

0000000080001f44 <destroy_pagetable>:

/*
 * 销毁页表
 */
void destroy_pagetable(pagetable_t pt)
{
    80001f44:	1141                	add	sp,sp,-16
    80001f46:	e406                	sd	ra,8(sp)
    80001f48:	e022                	sd	s0,0(sp)
    80001f4a:	0800                	add	s0,sp,16
    freewalk(pt, 2);
    80001f4c:	4589                	li	a1,2
    80001f4e:	c7dff0ef          	jal	80001bca <freewalk>
}
    80001f52:	60a2                	ld	ra,8(sp)
    80001f54:	6402                	ld	s0,0(sp)
    80001f56:	0141                	add	sp,sp,16
    80001f58:	8082                	ret

0000000080001f5a <dump_pagetable>:

/*
 * 打印页表内容（调试用）
 */
void dump_pagetable(pagetable_t pt, int level)
{
    80001f5a:	7159                	add	sp,sp,-112
    80001f5c:	f486                	sd	ra,104(sp)
    80001f5e:	f0a2                	sd	s0,96(sp)
    80001f60:	eca6                	sd	s1,88(sp)
    80001f62:	e8ca                	sd	s2,80(sp)
    80001f64:	e4ce                	sd	s3,72(sp)
    80001f66:	e0d2                	sd	s4,64(sp)
    80001f68:	fc56                	sd	s5,56(sp)
    80001f6a:	f85a                	sd	s6,48(sp)
    80001f6c:	f45e                	sd	s7,40(sp)
    80001f6e:	f062                	sd	s8,32(sp)
    80001f70:	ec66                	sd	s9,24(sp)
    80001f72:	e86a                	sd	s10,16(sp)
    80001f74:	e46e                	sd	s11,8(sp)
    80001f76:	1880                	add	s0,sp,112
    80001f78:	8a2e                	mv	s4,a1
    for (int i = 0; i < 512; i++) {
    80001f7a:	8aaa                	mv	s5,a0
    80001f7c:	4981                	li	s3,0
        pte_t pte = pt[i];
        if (pte & PTE_V) {
            for (int j = 0; j < level; j++) {
                printf("  ");
            }
            printf("Level %d[%d]: PTE=0x%lx PA=0x%lx", level, i, pte, PTE2PA(pte));
    80001f7e:	00003c17          	auipc	s8,0x3
    80001f82:	932c0c13          	add	s8,s8,-1742 # 800048b0 <digits+0x490>
            if (pte & PTE_R) printf(" R");
            if (pte & PTE_W) printf(" W");
            if (pte & PTE_X) printf(" X");
            if (pte & PTE_U) printf(" U");
            printf("\n");
    80001f86:	00002b97          	auipc	s7,0x2
    80001f8a:	d02b8b93          	add	s7,s7,-766 # 80003c88 <etext+0xc88>
            if (pte & PTE_U) printf(" U");
    80001f8e:	00003d97          	auipc	s11,0x3
    80001f92:	962d8d93          	add	s11,s11,-1694 # 800048f0 <digits+0x4d0>
            if (pte & PTE_X) printf(" X");
    80001f96:	00003d17          	auipc	s10,0x3
    80001f9a:	952d0d13          	add	s10,s10,-1710 # 800048e8 <digits+0x4c8>
            if (pte & PTE_W) printf(" W");
    80001f9e:	00003c97          	auipc	s9,0x3
    80001fa2:	942c8c93          	add	s9,s9,-1726 # 800048e0 <digits+0x4c0>
                printf("  ");
    80001fa6:	00003b17          	auipc	s6,0x3
    80001faa:	902b0b13          	add	s6,s6,-1790 # 800048a8 <digits+0x488>
    80001fae:	a815                	j	80001fe2 <dump_pagetable+0x88>
            if (pte & PTE_R) printf(" R");
    80001fb0:	00003517          	auipc	a0,0x3
    80001fb4:	92850513          	add	a0,a0,-1752 # 800048d8 <digits+0x4b8>
    80001fb8:	fddfe0ef          	jal	80000f94 <printf>
    80001fbc:	a8b1                	j	80002018 <dump_pagetable+0xbe>
            if (pte & PTE_W) printf(" W");
    80001fbe:	8566                	mv	a0,s9
    80001fc0:	fd5fe0ef          	jal	80000f94 <printf>
    80001fc4:	a8a9                	j	8000201e <dump_pagetable+0xc4>
            if (pte & PTE_X) printf(" X");
    80001fc6:	856a                	mv	a0,s10
    80001fc8:	fcdfe0ef          	jal	80000f94 <printf>
    80001fcc:	a8a1                	j	80002024 <dump_pagetable+0xca>
            if (pte & PTE_U) printf(" U");
    80001fce:	856e                	mv	a0,s11
    80001fd0:	fc5fe0ef          	jal	80000f94 <printf>
    80001fd4:	a8a1                	j	8000202c <dump_pagetable+0xd2>
    for (int i = 0; i < 512; i++) {
    80001fd6:	2985                	addw	s3,s3,1
    80001fd8:	0aa1                	add	s5,s5,8
    80001fda:	20000793          	li	a5,512
    80001fde:	06f98263          	beq	s3,a5,80002042 <dump_pagetable+0xe8>
        pte_t pte = pt[i];
    80001fe2:	000ab903          	ld	s2,0(s5)
        if (pte & PTE_V) {
    80001fe6:	00197793          	and	a5,s2,1
    80001fea:	d7f5                	beqz	a5,80001fd6 <dump_pagetable+0x7c>
            for (int j = 0; j < level; j++) {
    80001fec:	01405963          	blez	s4,80001ffe <dump_pagetable+0xa4>
    80001ff0:	4481                	li	s1,0
                printf("  ");
    80001ff2:	855a                	mv	a0,s6
    80001ff4:	fa1fe0ef          	jal	80000f94 <printf>
            for (int j = 0; j < level; j++) {
    80001ff8:	2485                	addw	s1,s1,1
    80001ffa:	fe9a1ce3          	bne	s4,s1,80001ff2 <dump_pagetable+0x98>
            printf("Level %d[%d]: PTE=0x%lx PA=0x%lx", level, i, pte, PTE2PA(pte));
    80001ffe:	00a95493          	srl	s1,s2,0xa
    80002002:	04b2                	sll	s1,s1,0xc
    80002004:	8726                	mv	a4,s1
    80002006:	86ca                	mv	a3,s2
    80002008:	864e                	mv	a2,s3
    8000200a:	85d2                	mv	a1,s4
    8000200c:	8562                	mv	a0,s8
    8000200e:	f87fe0ef          	jal	80000f94 <printf>
            if (pte & PTE_R) printf(" R");
    80002012:	00297793          	and	a5,s2,2
    80002016:	ffc9                	bnez	a5,80001fb0 <dump_pagetable+0x56>
            if (pte & PTE_W) printf(" W");
    80002018:	00497793          	and	a5,s2,4
    8000201c:	f3cd                	bnez	a5,80001fbe <dump_pagetable+0x64>
            if (pte & PTE_X) printf(" X");
    8000201e:	00897793          	and	a5,s2,8
    80002022:	f3d5                	bnez	a5,80001fc6 <dump_pagetable+0x6c>
            if (pte & PTE_U) printf(" U");
    80002024:	01097913          	and	s2,s2,16
    80002028:	fa0913e3          	bnez	s2,80001fce <dump_pagetable+0x74>
            printf("\n");
    8000202c:	855e                	mv	a0,s7
    8000202e:	f67fe0ef          	jal	80000f94 <printf>
            
            if (level > 0) {
    80002032:	fb4052e3          	blez	s4,80001fd6 <dump_pagetable+0x7c>
                dump_pagetable((pagetable_t)PTE2PA(pte), level - 1);
    80002036:	fffa059b          	addw	a1,s4,-1
    8000203a:	8526                	mv	a0,s1
    8000203c:	f1fff0ef          	jal	80001f5a <dump_pagetable>
    80002040:	bf59                	j	80001fd6 <dump_pagetable+0x7c>
            }
        }
    }
    80002042:	70a6                	ld	ra,104(sp)
    80002044:	7406                	ld	s0,96(sp)
    80002046:	64e6                	ld	s1,88(sp)
    80002048:	6946                	ld	s2,80(sp)
    8000204a:	69a6                	ld	s3,72(sp)
    8000204c:	6a06                	ld	s4,64(sp)
    8000204e:	7ae2                	ld	s5,56(sp)
    80002050:	7b42                	ld	s6,48(sp)
    80002052:	7ba2                	ld	s7,40(sp)
    80002054:	7c02                	ld	s8,32(sp)
    80002056:	6ce2                	ld	s9,24(sp)
    80002058:	6d42                	ld	s10,16(sp)
    8000205a:	6da2                	ld	s11,8(sp)
    8000205c:	6165                	add	sp,sp,112
    8000205e:	8082                	ret

0000000080002060 <test_kalloc_basic>:

/*
 * 基本分配测试
 */
void test_kalloc_basic(void)
{
    80002060:	1101                	add	sp,sp,-32
    80002062:	ec06                	sd	ra,24(sp)
    80002064:	e822                	sd	s0,16(sp)
    80002066:	e426                	sd	s1,8(sp)
    80002068:	e04a                	sd	s2,0(sp)
    8000206a:	1000                	add	s0,sp,32
    printf("  Testing basic allocation...\n");
    8000206c:	00003517          	auipc	a0,0x3
    80002070:	88c50513          	add	a0,a0,-1908 # 800048f8 <digits+0x4d8>
    80002074:	f21fe0ef          	jal	80000f94 <printf>
    
    // 测试分配
    void *page1 = alloc_page();
    80002078:	a7bff0ef          	jal	80001af2 <alloc_page>
    ASSERT(page1 != 0, "First allocation should succeed");
    8000207c:	c155                	beqz	a0,80002120 <test_kalloc_basic+0xc0>
    8000207e:	84aa                	mv	s1,a0
    80002080:	00004717          	auipc	a4,0x4
    80002084:	0b470713          	add	a4,a4,180 # 80006134 <tests_passed>
    80002088:	431c                	lw	a5,0(a4)
    8000208a:	0017869b          	addw	a3,a5,1
    8000208e:	c314                	sw	a3,0(a4)
    ASSERT(((uint64)page1 & 0xFFF) == 0, "Page should be aligned");
    80002090:	03451713          	sll	a4,a0,0x34
    80002094:	ef55                	bnez	a4,80002150 <test_kalloc_basic+0xf0>
    80002096:	2789                	addw	a5,a5,2
    80002098:	00004717          	auipc	a4,0x4
    8000209c:	08f72e23          	sw	a5,156(a4) # 80006134 <tests_passed>
    
    void *page2 = alloc_page();
    800020a0:	a53ff0ef          	jal	80001af2 <alloc_page>
    800020a4:	892a                	mv	s2,a0
    ASSERT(page2 != 0, "Second allocation should succeed");
    800020a6:	c175                	beqz	a0,8000218a <test_kalloc_basic+0x12a>
    800020a8:	00004797          	auipc	a5,0x4
    800020ac:	08c78793          	add	a5,a5,140 # 80006134 <tests_passed>
    800020b0:	4398                	lw	a4,0(a5)
    800020b2:	0017069b          	addw	a3,a4,1
    800020b6:	c394                	sw	a3,0(a5)
    ASSERT(page1 != page2, "Different allocations should return different pages");
    800020b8:	10a48163          	beq	s1,a0,800021ba <test_kalloc_basic+0x15a>
    800020bc:	00004797          	auipc	a5,0x4
    800020c0:	07878793          	add	a5,a5,120 # 80006134 <tests_passed>
    800020c4:	2709                	addw	a4,a4,2
    800020c6:	c398                	sw	a4,0(a5)
    
    // 测试数据写入
    *(int*)page1 = 0x12345678;
    800020c8:	12345737          	lui	a4,0x12345
    800020cc:	67870713          	add	a4,a4,1656 # 12345678 <_entry-0x6dcba988>
    800020d0:	c098                	sw	a4,0(s1)
    ASSERT(*(int*)page1 == 0x12345678, "Should be able to write to allocated page");
    800020d2:	4394                	lw	a3,0(a5)
    800020d4:	2685                	addw	a3,a3,1
    800020d6:	c394                	sw	a3,0(a5)
    
    *(int*)page2 = 0x87654321;
    800020d8:	876546b7          	lui	a3,0x87654
    800020dc:	32168693          	add	a3,a3,801 # ffffffff87654321 <tests_passed+0xffffffff0764e1ed>
    800020e0:	c114                	sw	a3,0(a0)
    ASSERT(*(int*)page2 == 0x87654321, "Should be able to write to second page");
    800020e2:	4394                	lw	a3,0(a5)
    800020e4:	0016861b          	addw	a2,a3,1
    800020e8:	c390                	sw	a2,0(a5)
    ASSERT(*(int*)page1 == 0x12345678, "First page should not be affected");
    800020ea:	409c                	lw	a5,0(s1)
    800020ec:	0ee78f63          	beq	a5,a4,800021ea <test_kalloc_basic+0x18a>
    800020f0:	03700693          	li	a3,55
    800020f4:	00003617          	auipc	a2,0x3
    800020f8:	82460613          	add	a2,a2,-2012 # 80004918 <digits+0x4f8>
    800020fc:	00003597          	auipc	a1,0x3
    80002100:	8ec58593          	add	a1,a1,-1812 # 800049e8 <digits+0x5c8>
    80002104:	00003517          	auipc	a0,0x3
    80002108:	84c50513          	add	a0,a0,-1972 # 80004950 <digits+0x530>
    8000210c:	e89fe0ef          	jal	80000f94 <printf>
    80002110:	00004717          	auipc	a4,0x4
    80002114:	02070713          	add	a4,a4,32 # 80006130 <tests_failed>
    80002118:	431c                	lw	a5,0(a4)
    8000211a:	2785                	addw	a5,a5,1
    8000211c:	c31c                	sw	a5,0(a4)
    8000211e:	a085                	j	8000217e <test_kalloc_basic+0x11e>
    ASSERT(page1 != 0, "First allocation should succeed");
    80002120:	02a00693          	li	a3,42
    80002124:	00002617          	auipc	a2,0x2
    80002128:	7f460613          	add	a2,a2,2036 # 80004918 <digits+0x4f8>
    8000212c:	00003597          	auipc	a1,0x3
    80002130:	80458593          	add	a1,a1,-2044 # 80004930 <digits+0x510>
    80002134:	00003517          	auipc	a0,0x3
    80002138:	81c50513          	add	a0,a0,-2020 # 80004950 <digits+0x530>
    8000213c:	e59fe0ef          	jal	80000f94 <printf>
    80002140:	00004717          	auipc	a4,0x4
    80002144:	ff070713          	add	a4,a4,-16 # 80006130 <tests_failed>
    80002148:	431c                	lw	a5,0(a4)
    8000214a:	2785                	addw	a5,a5,1
    8000214c:	c31c                	sw	a5,0(a4)
    8000214e:	a805                	j	8000217e <test_kalloc_basic+0x11e>
    ASSERT(((uint64)page1 & 0xFFF) == 0, "Page should be aligned");
    80002150:	02b00693          	li	a3,43
    80002154:	00002617          	auipc	a2,0x2
    80002158:	7c460613          	add	a2,a2,1988 # 80004918 <digits+0x4f8>
    8000215c:	00003597          	auipc	a1,0x3
    80002160:	81458593          	add	a1,a1,-2028 # 80004970 <digits+0x550>
    80002164:	00002517          	auipc	a0,0x2
    80002168:	7ec50513          	add	a0,a0,2028 # 80004950 <digits+0x530>
    8000216c:	e29fe0ef          	jal	80000f94 <printf>
    80002170:	00004717          	auipc	a4,0x4
    80002174:	fc070713          	add	a4,a4,-64 # 80006130 <tests_failed>
    80002178:	431c                	lw	a5,0(a4)
    8000217a:	2785                	addw	a5,a5,1
    8000217c:	c31c                	sw	a5,0(a4)
    ASSERT(page3 != 0, "Allocation after free should succeed");
    
    free_page(page3);
    
    printf("  Basic allocation tests passed\n");
}
    8000217e:	60e2                	ld	ra,24(sp)
    80002180:	6442                	ld	s0,16(sp)
    80002182:	64a2                	ld	s1,8(sp)
    80002184:	6902                	ld	s2,0(sp)
    80002186:	6105                	add	sp,sp,32
    80002188:	8082                	ret
    ASSERT(page2 != 0, "Second allocation should succeed");
    8000218a:	02e00693          	li	a3,46
    8000218e:	00002617          	auipc	a2,0x2
    80002192:	78a60613          	add	a2,a2,1930 # 80004918 <digits+0x4f8>
    80002196:	00002597          	auipc	a1,0x2
    8000219a:	7f258593          	add	a1,a1,2034 # 80004988 <digits+0x568>
    8000219e:	00002517          	auipc	a0,0x2
    800021a2:	7b250513          	add	a0,a0,1970 # 80004950 <digits+0x530>
    800021a6:	deffe0ef          	jal	80000f94 <printf>
    800021aa:	00004717          	auipc	a4,0x4
    800021ae:	f8670713          	add	a4,a4,-122 # 80006130 <tests_failed>
    800021b2:	431c                	lw	a5,0(a4)
    800021b4:	2785                	addw	a5,a5,1
    800021b6:	c31c                	sw	a5,0(a4)
    800021b8:	b7d9                	j	8000217e <test_kalloc_basic+0x11e>
    ASSERT(page1 != page2, "Different allocations should return different pages");
    800021ba:	02f00693          	li	a3,47
    800021be:	00002617          	auipc	a2,0x2
    800021c2:	75a60613          	add	a2,a2,1882 # 80004918 <digits+0x4f8>
    800021c6:	00002597          	auipc	a1,0x2
    800021ca:	7ea58593          	add	a1,a1,2026 # 800049b0 <digits+0x590>
    800021ce:	00002517          	auipc	a0,0x2
    800021d2:	78250513          	add	a0,a0,1922 # 80004950 <digits+0x530>
    800021d6:	dbffe0ef          	jal	80000f94 <printf>
    800021da:	00004717          	auipc	a4,0x4
    800021de:	f5670713          	add	a4,a4,-170 # 80006130 <tests_failed>
    800021e2:	431c                	lw	a5,0(a4)
    800021e4:	2785                	addw	a5,a5,1
    800021e6:	c31c                	sw	a5,0(a4)
    800021e8:	bf59                	j	8000217e <test_kalloc_basic+0x11e>
    ASSERT(*(int*)page1 == 0x12345678, "First page should not be affected");
    800021ea:	2689                	addw	a3,a3,2
    800021ec:	00004797          	auipc	a5,0x4
    800021f0:	f4d7a423          	sw	a3,-184(a5) # 80006134 <tests_passed>
    free_page(page1);
    800021f4:	8526                	mv	a0,s1
    800021f6:	f10ff0ef          	jal	80001906 <free_page>
    free_page(page2);
    800021fa:	854a                	mv	a0,s2
    800021fc:	f0aff0ef          	jal	80001906 <free_page>
    void *page3 = alloc_page();
    80002200:	8f3ff0ef          	jal	80001af2 <alloc_page>
    ASSERT(page3 != 0, "Allocation after free should succeed");
    80002204:	c10d                	beqz	a0,80002226 <test_kalloc_basic+0x1c6>
    80002206:	00004717          	auipc	a4,0x4
    8000220a:	f2e70713          	add	a4,a4,-210 # 80006134 <tests_passed>
    8000220e:	431c                	lw	a5,0(a4)
    80002210:	2785                	addw	a5,a5,1
    80002212:	c31c                	sw	a5,0(a4)
    free_page(page3);
    80002214:	ef2ff0ef          	jal	80001906 <free_page>
    printf("  Basic allocation tests passed\n");
    80002218:	00003517          	auipc	a0,0x3
    8000221c:	82050513          	add	a0,a0,-2016 # 80004a38 <digits+0x618>
    80002220:	d75fe0ef          	jal	80000f94 <printf>
    80002224:	bfa9                	j	8000217e <test_kalloc_basic+0x11e>
    ASSERT(page3 != 0, "Allocation after free should succeed");
    80002226:	03f00693          	li	a3,63
    8000222a:	00002617          	auipc	a2,0x2
    8000222e:	6ee60613          	add	a2,a2,1774 # 80004918 <digits+0x4f8>
    80002232:	00002597          	auipc	a1,0x2
    80002236:	7de58593          	add	a1,a1,2014 # 80004a10 <digits+0x5f0>
    8000223a:	00002517          	auipc	a0,0x2
    8000223e:	71650513          	add	a0,a0,1814 # 80004950 <digits+0x530>
    80002242:	d53fe0ef          	jal	80000f94 <printf>
    80002246:	00004717          	auipc	a4,0x4
    8000224a:	eea70713          	add	a4,a4,-278 # 80006130 <tests_failed>
    8000224e:	431c                	lw	a5,0(a4)
    80002250:	2785                	addw	a5,a5,1
    80002252:	c31c                	sw	a5,0(a4)
    80002254:	b72d                	j	8000217e <test_kalloc_basic+0x11e>

0000000080002256 <test_kalloc_stress>:

/*
 * 压力测试
 */
void test_kalloc_stress(void)
{
    80002256:	7175                	add	sp,sp,-144
    80002258:	e506                	sd	ra,136(sp)
    8000225a:	e122                	sd	s0,128(sp)
    8000225c:	fca6                	sd	s1,120(sp)
    8000225e:	f8ca                	sd	s2,112(sp)
    80002260:	f4ce                	sd	s3,104(sp)
    80002262:	f0d2                	sd	s4,96(sp)
    80002264:	ecd6                	sd	s5,88(sp)
    80002266:	e8da                	sd	s6,80(sp)
    80002268:	0900                	add	s0,sp,144
    printf("  Testing stress allocation...\n");
    8000226a:	00002517          	auipc	a0,0x2
    8000226e:	7f650513          	add	a0,a0,2038 # 80004a60 <digits+0x640>
    80002272:	d23fe0ef          	jal	80000f94 <printf>
    
    #define MAX_PAGES 10
    void *pages[MAX_PAGES];
    
    // 分配多个页面
    for (int i = 0; i < MAX_PAGES; i++) {
    80002276:	f7040913          	add	s2,s0,-144
    printf("  Testing stress allocation...\n");
    8000227a:	89ca                	mv	s3,s2
    for (int i = 0; i < MAX_PAGES; i++) {
    8000227c:	4481                	li	s1,0
            printf("  Warning: Could only allocate %d pages\n", i);
            break;
        }
        
        // 检查页面对齐
        ASSERT(((uint64)pages[i] & 0xFFF) == 0, "All pages should be aligned");
    8000227e:	6a85                	lui	s5,0x1
    80002280:	1afd                	add	s5,s5,-1 # fff <_entry-0x7ffff001>
    80002282:	00004a17          	auipc	s4,0x4
    80002286:	eb2a0a13          	add	s4,s4,-334 # 80006134 <tests_passed>
    for (int i = 0; i < MAX_PAGES; i++) {
    8000228a:	4b29                	li	s6,10
        pages[i] = alloc_page();
    8000228c:	867ff0ef          	jal	80001af2 <alloc_page>
    80002290:	00a9b023          	sd	a0,0(s3)
        if (pages[i] == 0) {
    80002294:	c93d                	beqz	a0,8000230a <test_kalloc_stress+0xb4>
        ASSERT(((uint64)pages[i] & 0xFFF) == 0, "All pages should be aligned");
    80002296:	015577b3          	and	a5,a0,s5
    8000229a:	e3c1                	bnez	a5,8000231a <test_kalloc_stress+0xc4>
    8000229c:	000a2783          	lw	a5,0(s4)
    800022a0:	2785                	addw	a5,a5,1
    800022a2:	00fa2023          	sw	a5,0(s4)
        
        // 写入测试数据
        *(int*)pages[i] = i;
    800022a6:	c104                	sw	s1,0(a0)
    for (int i = 0; i < MAX_PAGES; i++) {
    800022a8:	2485                	addw	s1,s1,1
    800022aa:	09a1                	add	s3,s3,8
    800022ac:	ff6490e3          	bne	s1,s6,8000228c <test_kalloc_stress+0x36>
    800022b0:	86ca                	mv	a3,s2
    800022b2:	4781                	li	a5,0
    }
    
    // 验证数据完整性
    for (int i = 0; i < MAX_PAGES && pages[i] != 0; i++) {
        ASSERT(*(int*)pages[i] == i, "Page data should be preserved");
    800022b4:	00004617          	auipc	a2,0x4
    800022b8:	e8060613          	add	a2,a2,-384 # 80006134 <tests_passed>
    for (int i = 0; i < MAX_PAGES && pages[i] != 0; i++) {
    800022bc:	45a9                	li	a1,10
    800022be:	6298                	ld	a4,0(a3)
    800022c0:	cb19                	beqz	a4,800022d6 <test_kalloc_stress+0x80>
        ASSERT(*(int*)pages[i] == i, "Page data should be preserved");
    800022c2:	4318                	lw	a4,0(a4)
    800022c4:	08f71563          	bne	a4,a5,8000234e <test_kalloc_stress+0xf8>
    800022c8:	4218                	lw	a4,0(a2)
    800022ca:	2705                	addw	a4,a4,1
    800022cc:	c218                	sw	a4,0(a2)
    for (int i = 0; i < MAX_PAGES && pages[i] != 0; i++) {
    800022ce:	2785                	addw	a5,a5,1
    800022d0:	06a1                	add	a3,a3,8
    800022d2:	feb796e3          	bne	a5,a1,800022be <test_kalloc_stress+0x68>
    }
    
    // 释放所有页面
    for (int i = 0; i < MAX_PAGES && pages[i] != 0; i++) {
    800022d6:	05090493          	add	s1,s2,80
    800022da:	00093503          	ld	a0,0(s2)
    800022de:	c511                	beqz	a0,800022ea <test_kalloc_stress+0x94>
        free_page(pages[i]);
    800022e0:	e26ff0ef          	jal	80001906 <free_page>
    for (int i = 0; i < MAX_PAGES && pages[i] != 0; i++) {
    800022e4:	0921                	add	s2,s2,8
    800022e6:	ff249ae3          	bne	s1,s2,800022da <test_kalloc_stress+0x84>
    }
    
    printf("  Stress allocation tests passed\n");
    800022ea:	00003517          	auipc	a0,0x3
    800022ee:	80650513          	add	a0,a0,-2042 # 80004af0 <digits+0x6d0>
    800022f2:	ca3fe0ef          	jal	80000f94 <printf>
}
    800022f6:	60aa                	ld	ra,136(sp)
    800022f8:	640a                	ld	s0,128(sp)
    800022fa:	74e6                	ld	s1,120(sp)
    800022fc:	7946                	ld	s2,112(sp)
    800022fe:	79a6                	ld	s3,104(sp)
    80002300:	7a06                	ld	s4,96(sp)
    80002302:	6ae6                	ld	s5,88(sp)
    80002304:	6b46                	ld	s6,80(sp)
    80002306:	6149                	add	sp,sp,144
    80002308:	8082                	ret
            printf("  Warning: Could only allocate %d pages\n", i);
    8000230a:	85a6                	mv	a1,s1
    8000230c:	00002517          	auipc	a0,0x2
    80002310:	77450513          	add	a0,a0,1908 # 80004a80 <digits+0x660>
    80002314:	c81fe0ef          	jal	80000f94 <printf>
            break;
    80002318:	bf61                	j	800022b0 <test_kalloc_stress+0x5a>
        ASSERT(((uint64)pages[i] & 0xFFF) == 0, "All pages should be aligned");
    8000231a:	05900693          	li	a3,89
    8000231e:	00002617          	auipc	a2,0x2
    80002322:	5fa60613          	add	a2,a2,1530 # 80004918 <digits+0x4f8>
    80002326:	00002597          	auipc	a1,0x2
    8000232a:	78a58593          	add	a1,a1,1930 # 80004ab0 <digits+0x690>
    8000232e:	00002517          	auipc	a0,0x2
    80002332:	62250513          	add	a0,a0,1570 # 80004950 <digits+0x530>
    80002336:	c5ffe0ef          	jal	80000f94 <printf>
    8000233a:	00004797          	auipc	a5,0x4
    8000233e:	df67a783          	lw	a5,-522(a5) # 80006130 <tests_failed>
    80002342:	2785                	addw	a5,a5,1
    80002344:	00004717          	auipc	a4,0x4
    80002348:	def72623          	sw	a5,-532(a4) # 80006130 <tests_failed>
    8000234c:	b76d                	j	800022f6 <test_kalloc_stress+0xa0>
        ASSERT(*(int*)pages[i] == i, "Page data should be preserved");
    8000234e:	06100693          	li	a3,97
    80002352:	00002617          	auipc	a2,0x2
    80002356:	5c660613          	add	a2,a2,1478 # 80004918 <digits+0x4f8>
    8000235a:	00002597          	auipc	a1,0x2
    8000235e:	77658593          	add	a1,a1,1910 # 80004ad0 <digits+0x6b0>
    80002362:	00002517          	auipc	a0,0x2
    80002366:	5ee50513          	add	a0,a0,1518 # 80004950 <digits+0x530>
    8000236a:	c2bfe0ef          	jal	80000f94 <printf>
    8000236e:	00004797          	auipc	a5,0x4
    80002372:	dc27a783          	lw	a5,-574(a5) # 80006130 <tests_failed>
    80002376:	2785                	addw	a5,a5,1
    80002378:	b7f1                	j	80002344 <test_kalloc_stress+0xee>

000000008000237a <test_physical_memory>:
{
    8000237a:	1141                	add	sp,sp,-16
    8000237c:	e406                	sd	ra,8(sp)
    8000237e:	e022                	sd	s0,0(sp)
    80002380:	0800                	add	s0,sp,16
    TEST_START("Physical Memory Allocator");
    80002382:	00002597          	auipc	a1,0x2
    80002386:	79658593          	add	a1,a1,1942 # 80004b18 <digits+0x6f8>
    8000238a:	00001517          	auipc	a0,0x1
    8000238e:	0a650513          	add	a0,a0,166 # 80003430 <etext+0x430>
    80002392:	c03fe0ef          	jal	80000f94 <printf>
    test_kalloc_basic();
    80002396:	ccbff0ef          	jal	80002060 <test_kalloc_basic>
    test_kalloc_stress();
    8000239a:	ebdff0ef          	jal	80002256 <test_kalloc_stress>
    TEST_END("Physical Memory Allocator");
    8000239e:	00002597          	auipc	a1,0x2
    800023a2:	77a58593          	add	a1,a1,1914 # 80004b18 <digits+0x6f8>
    800023a6:	00001517          	auipc	a0,0x1
    800023aa:	1fa50513          	add	a0,a0,506 # 800035a0 <etext+0x5a0>
    800023ae:	be7fe0ef          	jal	80000f94 <printf>
}
    800023b2:	60a2                	ld	ra,8(sp)
    800023b4:	6402                	ld	s0,0(sp)
    800023b6:	0141                	add	sp,sp,16
    800023b8:	8082                	ret

00000000800023ba <test_page_mapping>:

/*
 * 页面映射测试
 */
void test_page_mapping(void)
{
    800023ba:	7179                	add	sp,sp,-48
    800023bc:	f406                	sd	ra,40(sp)
    800023be:	f022                	sd	s0,32(sp)
    800023c0:	ec26                	sd	s1,24(sp)
    800023c2:	e84a                	sd	s2,16(sp)
    800023c4:	e44e                	sd	s3,8(sp)
    800023c6:	1800                	add	s0,sp,48
    printf("  Testing page mapping...\n");
    800023c8:	00002517          	auipc	a0,0x2
    800023cc:	77050513          	add	a0,a0,1904 # 80004b38 <digits+0x718>
    800023d0:	bc5fe0ef          	jal	80000f94 <printf>
    
    // 创建测试页表
    pagetable_t pt = create_pagetable();
    800023d4:	853ff0ef          	jal	80001c26 <create_pagetable>
    ASSERT(pt != 0, "Should be able to create page table");
    800023d8:	c159                	beqz	a0,8000245e <test_page_mapping+0xa4>
    800023da:	84aa                	mv	s1,a0
    800023dc:	00004717          	auipc	a4,0x4
    800023e0:	d5870713          	add	a4,a4,-680 # 80006134 <tests_passed>
    800023e4:	431c                	lw	a5,0(a4)
    800023e6:	2785                	addw	a5,a5,1
    800023e8:	c31c                	sw	a5,0(a4)
    
    // 分配物理页面
    void *pa = alloc_page();
    800023ea:	f08ff0ef          	jal	80001af2 <alloc_page>
    800023ee:	892a                	mv	s2,a0
    ASSERT(pa != 0, "Should be able to allocate physical page");
    800023f0:	cd59                	beqz	a0,8000248e <test_page_mapping+0xd4>
    800023f2:	00004717          	auipc	a4,0x4
    800023f6:	d4270713          	add	a4,a4,-702 # 80006134 <tests_passed>
    800023fa:	431c                	lw	a5,0(a4)
    800023fc:	2785                	addw	a5,a5,1
    800023fe:	c31c                	sw	a5,0(a4)
    
    // 测试映射
    uint64 va = 0x1000000;  // 测试虚拟地址
    int result = map_pages(pt, va, PGSIZE, (uint64)pa, PTE_R | PTE_W);
    80002400:	4719                	li	a4,6
    80002402:	86aa                	mv	a3,a0
    80002404:	6605                	lui	a2,0x1
    80002406:	010005b7          	lui	a1,0x1000
    8000240a:	8526                	mv	a0,s1
    8000240c:	913ff0ef          	jal	80001d1e <map_pages>
    ASSERT(result == 0, "Mapping should succeed");
    80002410:	e55d                	bnez	a0,800024be <test_page_mapping+0x104>
    80002412:	00004717          	auipc	a4,0x4
    80002416:	d2270713          	add	a4,a4,-734 # 80006134 <tests_passed>
    8000241a:	431c                	lw	a5,0(a4)
    8000241c:	2785                	addw	a5,a5,1
    8000241e:	c31c                	sw	a5,0(a4)
    
    // 测试地址转换
    uint64 translated_pa = walkaddr(pt, va);
    80002420:	010005b7          	lui	a1,0x1000
    80002424:	8526                	mv	a0,s1
    80002426:	8c3ff0ef          	jal	80001ce8 <walkaddr>
    ASSERT(translated_pa == (uint64)pa, "Address translation should work");
    8000242a:	0ca90863          	beq	s2,a0,800024fa <test_page_mapping+0x140>
    8000242e:	08f00693          	li	a3,143
    80002432:	00002617          	auipc	a2,0x2
    80002436:	4e660613          	add	a2,a2,1254 # 80004918 <digits+0x4f8>
    8000243a:	00002597          	auipc	a1,0x2
    8000243e:	78e58593          	add	a1,a1,1934 # 80004bc8 <digits+0x7a8>
    80002442:	00002517          	auipc	a0,0x2
    80002446:	50e50513          	add	a0,a0,1294 # 80004950 <digits+0x530>
    8000244a:	b4bfe0ef          	jal	80000f94 <printf>
    8000244e:	00004717          	auipc	a4,0x4
    80002452:	ce270713          	add	a4,a4,-798 # 80006130 <tests_failed>
    80002456:	431c                	lw	a5,0(a4)
    80002458:	2785                	addw	a5,a5,1
    8000245a:	c31c                	sw	a5,0(a4)
    8000245c:	a841                	j	800024ec <test_page_mapping+0x132>
    ASSERT(pt != 0, "Should be able to create page table");
    8000245e:	08200693          	li	a3,130
    80002462:	00002617          	auipc	a2,0x2
    80002466:	4b660613          	add	a2,a2,1206 # 80004918 <digits+0x4f8>
    8000246a:	00002597          	auipc	a1,0x2
    8000246e:	6ee58593          	add	a1,a1,1774 # 80004b58 <digits+0x738>
    80002472:	00002517          	auipc	a0,0x2
    80002476:	4de50513          	add	a0,a0,1246 # 80004950 <digits+0x530>
    8000247a:	b1bfe0ef          	jal	80000f94 <printf>
    8000247e:	00004717          	auipc	a4,0x4
    80002482:	cb270713          	add	a4,a4,-846 # 80006130 <tests_failed>
    80002486:	431c                	lw	a5,0(a4)
    80002488:	2785                	addw	a5,a5,1
    8000248a:	c31c                	sw	a5,0(a4)
    8000248c:	a085                	j	800024ec <test_page_mapping+0x132>
    ASSERT(pa != 0, "Should be able to allocate physical page");
    8000248e:	08600693          	li	a3,134
    80002492:	00002617          	auipc	a2,0x2
    80002496:	48660613          	add	a2,a2,1158 # 80004918 <digits+0x4f8>
    8000249a:	00002597          	auipc	a1,0x2
    8000249e:	6e658593          	add	a1,a1,1766 # 80004b80 <digits+0x760>
    800024a2:	00002517          	auipc	a0,0x2
    800024a6:	4ae50513          	add	a0,a0,1198 # 80004950 <digits+0x530>
    800024aa:	aebfe0ef          	jal	80000f94 <printf>
    800024ae:	00004717          	auipc	a4,0x4
    800024b2:	c8270713          	add	a4,a4,-894 # 80006130 <tests_failed>
    800024b6:	431c                	lw	a5,0(a4)
    800024b8:	2785                	addw	a5,a5,1
    800024ba:	c31c                	sw	a5,0(a4)
    800024bc:	a805                	j	800024ec <test_page_mapping+0x132>
    ASSERT(result == 0, "Mapping should succeed");
    800024be:	08b00693          	li	a3,139
    800024c2:	00002617          	auipc	a2,0x2
    800024c6:	45660613          	add	a2,a2,1110 # 80004918 <digits+0x4f8>
    800024ca:	00002597          	auipc	a1,0x2
    800024ce:	6e658593          	add	a1,a1,1766 # 80004bb0 <digits+0x790>
    800024d2:	00002517          	auipc	a0,0x2
    800024d6:	47e50513          	add	a0,a0,1150 # 80004950 <digits+0x530>
    800024da:	abbfe0ef          	jal	80000f94 <printf>
    800024de:	00004717          	auipc	a4,0x4
    800024e2:	c5270713          	add	a4,a4,-942 # 80006130 <tests_failed>
    800024e6:	431c                	lw	a5,0(a4)
    800024e8:	2785                	addw	a5,a5,1
    800024ea:	c31c                	sw	a5,0(a4)
    // 清理
    destroy_pagetable(pt);
    free_page(pa);
    
    printf("  Page mapping tests passed\n");
}
    800024ec:	70a2                	ld	ra,40(sp)
    800024ee:	7402                	ld	s0,32(sp)
    800024f0:	64e2                	ld	s1,24(sp)
    800024f2:	6942                	ld	s2,16(sp)
    800024f4:	69a2                	ld	s3,8(sp)
    800024f6:	6145                	add	sp,sp,48
    800024f8:	8082                	ret
    ASSERT(translated_pa == (uint64)pa, "Address translation should work");
    800024fa:	00004717          	auipc	a4,0x4
    800024fe:	c3a70713          	add	a4,a4,-966 # 80006134 <tests_passed>
    80002502:	431c                	lw	a5,0(a4)
    80002504:	2785                	addw	a5,a5,1
    80002506:	c31c                	sw	a5,0(a4)
    result = map_pages(pt, va, PGSIZE, (uint64)pa, PTE_R | PTE_W);
    80002508:	4719                	li	a4,6
    8000250a:	86ca                	mv	a3,s2
    8000250c:	6605                	lui	a2,0x1
    8000250e:	010005b7          	lui	a1,0x1000
    80002512:	8526                	mv	a0,s1
    80002514:	80bff0ef          	jal	80001d1e <map_pages>
    ASSERT(result != 0, "Duplicate mapping should fail");
    80002518:	c50d                	beqz	a0,80002542 <test_page_mapping+0x188>
    8000251a:	00004717          	auipc	a4,0x4
    8000251e:	c1a70713          	add	a4,a4,-998 # 80006134 <tests_passed>
    80002522:	431c                	lw	a5,0(a4)
    80002524:	2785                	addw	a5,a5,1
    80002526:	c31c                	sw	a5,0(a4)
    destroy_pagetable(pt);
    80002528:	8526                	mv	a0,s1
    8000252a:	a1bff0ef          	jal	80001f44 <destroy_pagetable>
    free_page(pa);
    8000252e:	854a                	mv	a0,s2
    80002530:	bd6ff0ef          	jal	80001906 <free_page>
    printf("  Page mapping tests passed\n");
    80002534:	00002517          	auipc	a0,0x2
    80002538:	6d450513          	add	a0,a0,1748 # 80004c08 <digits+0x7e8>
    8000253c:	a59fe0ef          	jal	80000f94 <printf>
    80002540:	b775                	j	800024ec <test_page_mapping+0x132>
    ASSERT(result != 0, "Duplicate mapping should fail");
    80002542:	09300693          	li	a3,147
    80002546:	00002617          	auipc	a2,0x2
    8000254a:	3d260613          	add	a2,a2,978 # 80004918 <digits+0x4f8>
    8000254e:	00002597          	auipc	a1,0x2
    80002552:	69a58593          	add	a1,a1,1690 # 80004be8 <digits+0x7c8>
    80002556:	00002517          	auipc	a0,0x2
    8000255a:	3fa50513          	add	a0,a0,1018 # 80004950 <digits+0x530>
    8000255e:	a37fe0ef          	jal	80000f94 <printf>
    80002562:	00004717          	auipc	a4,0x4
    80002566:	bce70713          	add	a4,a4,-1074 # 80006130 <tests_failed>
    8000256a:	431c                	lw	a5,0(a4)
    8000256c:	2785                	addw	a5,a5,1
    8000256e:	c31c                	sw	a5,0(a4)
    80002570:	bfb5                	j	800024ec <test_page_mapping+0x132>

0000000080002572 <test_address_translation>:

/*
 * 地址转换测试
 */
void test_address_translation(void)
{
    80002572:	7179                	add	sp,sp,-48
    80002574:	f406                	sd	ra,40(sp)
    80002576:	f022                	sd	s0,32(sp)
    80002578:	ec26                	sd	s1,24(sp)
    8000257a:	e84a                	sd	s2,16(sp)
    8000257c:	e44e                	sd	s3,8(sp)
    8000257e:	1800                	add	s0,sp,48
    printf("  Testing address translation...\n");
    80002580:	00002517          	auipc	a0,0x2
    80002584:	6a850513          	add	a0,a0,1704 # 80004c28 <digits+0x808>
    80002588:	a0dfe0ef          	jal	80000f94 <printf>
    
    pagetable_t pt = create_pagetable();
    8000258c:	e9aff0ef          	jal	80001c26 <create_pagetable>
    ASSERT(pt != 0, "Should be able to create page table");
    80002590:	c145                	beqz	a0,80002630 <test_address_translation+0xbe>
    80002592:	84aa                	mv	s1,a0
    80002594:	00004717          	auipc	a4,0x4
    80002598:	ba070713          	add	a4,a4,-1120 # 80006134 <tests_passed>
    8000259c:	431c                	lw	a5,0(a4)
    8000259e:	2785                	addw	a5,a5,1
    800025a0:	c31c                	sw	a5,0(a4)
    
    // 测试未映射地址
    uint64 unmapped_va = 0x2000000;
    uint64 pa = walkaddr(pt, unmapped_va);
    800025a2:	020005b7          	lui	a1,0x2000
    800025a6:	f42ff0ef          	jal	80001ce8 <walkaddr>
    ASSERT(pa == 0, "Unmapped address should return 0");
    800025aa:	e95d                	bnez	a0,80002660 <test_address_translation+0xee>
    800025ac:	00004717          	auipc	a4,0x4
    800025b0:	b8870713          	add	a4,a4,-1144 # 80006134 <tests_passed>
    800025b4:	431c                	lw	a5,0(a4)
    800025b6:	2785                	addw	a5,a5,1
    800025b8:	c31c                	sw	a5,0(a4)
    
    // 映射地址并测试
    void *phys_page = alloc_page();
    800025ba:	d38ff0ef          	jal	80001af2 <alloc_page>
    800025be:	892a                	mv	s2,a0
    ASSERT(phys_page != 0, "Should allocate physical page");
    800025c0:	cd71                	beqz	a0,8000269c <test_address_translation+0x12a>
    800025c2:	00004717          	auipc	a4,0x4
    800025c6:	b7270713          	add	a4,a4,-1166 # 80006134 <tests_passed>
    800025ca:	431c                	lw	a5,0(a4)
    800025cc:	2785                	addw	a5,a5,1
    800025ce:	c31c                	sw	a5,0(a4)
    
    uint64 test_va = 0x3000000;
    int result = map_pages(pt, test_va, PGSIZE, (uint64)phys_page, PTE_R | PTE_W | PTE_X);
    800025d0:	4739                	li	a4,14
    800025d2:	86aa                	mv	a3,a0
    800025d4:	6605                	lui	a2,0x1
    800025d6:	030005b7          	lui	a1,0x3000
    800025da:	8526                	mv	a0,s1
    800025dc:	f42ff0ef          	jal	80001d1e <map_pages>
    ASSERT(result == 0, "Mapping should succeed");
    800025e0:	0e051663          	bnez	a0,800026cc <test_address_translation+0x15a>
    800025e4:	00004717          	auipc	a4,0x4
    800025e8:	b5070713          	add	a4,a4,-1200 # 80006134 <tests_passed>
    800025ec:	431c                	lw	a5,0(a4)
    800025ee:	2785                	addw	a5,a5,1
    800025f0:	c31c                	sw	a5,0(a4)
    
    pa = walkaddr(pt, test_va);
    800025f2:	030005b7          	lui	a1,0x3000
    800025f6:	8526                	mv	a0,s1
    800025f8:	ef0ff0ef          	jal	80001ce8 <walkaddr>
    ASSERT(pa == (uint64)phys_page, "Translation should return correct physical address");
    800025fc:	10a90063          	beq	s2,a0,800026fc <test_address_translation+0x18a>
    80002600:	0b400693          	li	a3,180
    80002604:	00002617          	auipc	a2,0x2
    80002608:	31460613          	add	a2,a2,788 # 80004918 <digits+0x4f8>
    8000260c:	00002597          	auipc	a1,0x2
    80002610:	68c58593          	add	a1,a1,1676 # 80004c98 <digits+0x878>
    80002614:	00002517          	auipc	a0,0x2
    80002618:	33c50513          	add	a0,a0,828 # 80004950 <digits+0x530>
    8000261c:	979fe0ef          	jal	80000f94 <printf>
    80002620:	00004717          	auipc	a4,0x4
    80002624:	b1070713          	add	a4,a4,-1264 # 80006130 <tests_failed>
    80002628:	431c                	lw	a5,0(a4)
    8000262a:	2785                	addw	a5,a5,1
    8000262c:	c31c                	sw	a5,0(a4)
    8000262e:	a085                	j	8000268e <test_address_translation+0x11c>
    ASSERT(pt != 0, "Should be able to create page table");
    80002630:	0a400693          	li	a3,164
    80002634:	00002617          	auipc	a2,0x2
    80002638:	2e460613          	add	a2,a2,740 # 80004918 <digits+0x4f8>
    8000263c:	00002597          	auipc	a1,0x2
    80002640:	51c58593          	add	a1,a1,1308 # 80004b58 <digits+0x738>
    80002644:	00002517          	auipc	a0,0x2
    80002648:	30c50513          	add	a0,a0,780 # 80004950 <digits+0x530>
    8000264c:	949fe0ef          	jal	80000f94 <printf>
    80002650:	00004717          	auipc	a4,0x4
    80002654:	ae070713          	add	a4,a4,-1312 # 80006130 <tests_failed>
    80002658:	431c                	lw	a5,0(a4)
    8000265a:	2785                	addw	a5,a5,1
    8000265c:	c31c                	sw	a5,0(a4)
    8000265e:	a805                	j	8000268e <test_address_translation+0x11c>
    ASSERT(pa == 0, "Unmapped address should return 0");
    80002660:	0a900693          	li	a3,169
    80002664:	00002617          	auipc	a2,0x2
    80002668:	2b460613          	add	a2,a2,692 # 80004918 <digits+0x4f8>
    8000266c:	00002597          	auipc	a1,0x2
    80002670:	5e458593          	add	a1,a1,1508 # 80004c50 <digits+0x830>
    80002674:	00002517          	auipc	a0,0x2
    80002678:	2dc50513          	add	a0,a0,732 # 80004950 <digits+0x530>
    8000267c:	919fe0ef          	jal	80000f94 <printf>
    80002680:	00004717          	auipc	a4,0x4
    80002684:	ab070713          	add	a4,a4,-1360 # 80006130 <tests_failed>
    80002688:	431c                	lw	a5,0(a4)
    8000268a:	2785                	addw	a5,a5,1
    8000268c:	c31c                	sw	a5,0(a4)
    // 清理
    destroy_pagetable(pt);
    free_page(phys_page);
    
    printf("  Address translation tests passed\n");
}
    8000268e:	70a2                	ld	ra,40(sp)
    80002690:	7402                	ld	s0,32(sp)
    80002692:	64e2                	ld	s1,24(sp)
    80002694:	6942                	ld	s2,16(sp)
    80002696:	69a2                	ld	s3,8(sp)
    80002698:	6145                	add	sp,sp,48
    8000269a:	8082                	ret
    ASSERT(phys_page != 0, "Should allocate physical page");
    8000269c:	0ad00693          	li	a3,173
    800026a0:	00002617          	auipc	a2,0x2
    800026a4:	27860613          	add	a2,a2,632 # 80004918 <digits+0x4f8>
    800026a8:	00002597          	auipc	a1,0x2
    800026ac:	5d058593          	add	a1,a1,1488 # 80004c78 <digits+0x858>
    800026b0:	00002517          	auipc	a0,0x2
    800026b4:	2a050513          	add	a0,a0,672 # 80004950 <digits+0x530>
    800026b8:	8ddfe0ef          	jal	80000f94 <printf>
    800026bc:	00004717          	auipc	a4,0x4
    800026c0:	a7470713          	add	a4,a4,-1420 # 80006130 <tests_failed>
    800026c4:	431c                	lw	a5,0(a4)
    800026c6:	2785                	addw	a5,a5,1
    800026c8:	c31c                	sw	a5,0(a4)
    800026ca:	b7d1                	j	8000268e <test_address_translation+0x11c>
    ASSERT(result == 0, "Mapping should succeed");
    800026cc:	0b100693          	li	a3,177
    800026d0:	00002617          	auipc	a2,0x2
    800026d4:	24860613          	add	a2,a2,584 # 80004918 <digits+0x4f8>
    800026d8:	00002597          	auipc	a1,0x2
    800026dc:	4d858593          	add	a1,a1,1240 # 80004bb0 <digits+0x790>
    800026e0:	00002517          	auipc	a0,0x2
    800026e4:	27050513          	add	a0,a0,624 # 80004950 <digits+0x530>
    800026e8:	8adfe0ef          	jal	80000f94 <printf>
    800026ec:	00004717          	auipc	a4,0x4
    800026f0:	a4470713          	add	a4,a4,-1468 # 80006130 <tests_failed>
    800026f4:	431c                	lw	a5,0(a4)
    800026f6:	2785                	addw	a5,a5,1
    800026f8:	c31c                	sw	a5,0(a4)
    800026fa:	bf51                	j	8000268e <test_address_translation+0x11c>
    ASSERT(pa == (uint64)phys_page, "Translation should return correct physical address");
    800026fc:	00004717          	auipc	a4,0x4
    80002700:	a3870713          	add	a4,a4,-1480 # 80006134 <tests_passed>
    80002704:	431c                	lw	a5,0(a4)
    80002706:	2785                	addw	a5,a5,1
    80002708:	c31c                	sw	a5,0(a4)
    pa = walkaddr(pt, test_va + 0x123);
    8000270a:	030005b7          	lui	a1,0x3000
    8000270e:	12358593          	add	a1,a1,291 # 3000123 <_entry-0x7cfffedd>
    80002712:	8526                	mv	a0,s1
    80002714:	dd4ff0ef          	jal	80001ce8 <walkaddr>
    ASSERT(pa == (uint64)phys_page, "Translation should work for page-aligned address");
    80002718:	02a90a63          	beq	s2,a0,8000274c <test_address_translation+0x1da>
    8000271c:	0b800693          	li	a3,184
    80002720:	00002617          	auipc	a2,0x2
    80002724:	1f860613          	add	a2,a2,504 # 80004918 <digits+0x4f8>
    80002728:	00002597          	auipc	a1,0x2
    8000272c:	5a858593          	add	a1,a1,1448 # 80004cd0 <digits+0x8b0>
    80002730:	00002517          	auipc	a0,0x2
    80002734:	22050513          	add	a0,a0,544 # 80004950 <digits+0x530>
    80002738:	85dfe0ef          	jal	80000f94 <printf>
    8000273c:	00004717          	auipc	a4,0x4
    80002740:	9f470713          	add	a4,a4,-1548 # 80006130 <tests_failed>
    80002744:	431c                	lw	a5,0(a4)
    80002746:	2785                	addw	a5,a5,1
    80002748:	c31c                	sw	a5,0(a4)
    8000274a:	b791                	j	8000268e <test_address_translation+0x11c>
    8000274c:	00004717          	auipc	a4,0x4
    80002750:	9e870713          	add	a4,a4,-1560 # 80006134 <tests_passed>
    80002754:	431c                	lw	a5,0(a4)
    80002756:	2785                	addw	a5,a5,1
    80002758:	c31c                	sw	a5,0(a4)
    destroy_pagetable(pt);
    8000275a:	8526                	mv	a0,s1
    8000275c:	fe8ff0ef          	jal	80001f44 <destroy_pagetable>
    free_page(phys_page);
    80002760:	854a                	mv	a0,s2
    80002762:	9a4ff0ef          	jal	80001906 <free_page>
    printf("  Address translation tests passed\n");
    80002766:	00002517          	auipc	a0,0x2
    8000276a:	5a250513          	add	a0,a0,1442 # 80004d08 <digits+0x8e8>
    8000276e:	827fe0ef          	jal	80000f94 <printf>
    80002772:	bf31                	j	8000268e <test_address_translation+0x11c>

0000000080002774 <test_pagetable>:
{
    80002774:	1141                	add	sp,sp,-16
    80002776:	e406                	sd	ra,8(sp)
    80002778:	e022                	sd	s0,0(sp)
    8000277a:	0800                	add	s0,sp,16
    TEST_START("Page Table Management");
    8000277c:	00002597          	auipc	a1,0x2
    80002780:	5b458593          	add	a1,a1,1460 # 80004d30 <digits+0x910>
    80002784:	00001517          	auipc	a0,0x1
    80002788:	cac50513          	add	a0,a0,-852 # 80003430 <etext+0x430>
    8000278c:	809fe0ef          	jal	80000f94 <printf>
    test_page_mapping();
    80002790:	c2bff0ef          	jal	800023ba <test_page_mapping>
    test_address_translation();
    80002794:	ddfff0ef          	jal	80002572 <test_address_translation>
    TEST_END("Page Table Management");
    80002798:	00002597          	auipc	a1,0x2
    8000279c:	59858593          	add	a1,a1,1432 # 80004d30 <digits+0x910>
    800027a0:	00001517          	auipc	a0,0x1
    800027a4:	e0050513          	add	a0,a0,-512 # 800035a0 <etext+0x5a0>
    800027a8:	fecfe0ef          	jal	80000f94 <printf>
}
    800027ac:	60a2                	ld	ra,8(sp)
    800027ae:	6402                	ld	s0,0(sp)
    800027b0:	0141                	add	sp,sp,16
    800027b2:	8082                	ret

00000000800027b4 <test_virtual_memory>:

/*
 * 测试虚拟内存激活
 */
void test_virtual_memory(void)
{
    800027b4:	1101                	add	sp,sp,-32
    800027b6:	ec06                	sd	ra,24(sp)
    800027b8:	e822                	sd	s0,16(sp)
    800027ba:	e426                	sd	s1,8(sp)
    800027bc:	e04a                	sd	s2,0(sp)
    800027be:	1000                	add	s0,sp,32
    TEST_START("Virtual Memory Activation");
    800027c0:	00002597          	auipc	a1,0x2
    800027c4:	58858593          	add	a1,a1,1416 # 80004d48 <digits+0x928>
    800027c8:	00001517          	auipc	a0,0x1
    800027cc:	c6850513          	add	a0,a0,-920 # 80003430 <etext+0x430>
    800027d0:	fc4fe0ef          	jal	80000f94 <printf>
    
    printf("  Before enabling paging...\n");
    800027d4:	00002517          	auipc	a0,0x2
    800027d8:	59450513          	add	a0,a0,1428 # 80004d68 <digits+0x948>
    800027dc:	fb8fe0ef          	jal	80000f94 <printf>
    asm volatile("csrr %0, satp" : "=r" (x));
    800027e0:	180024f3          	csrr	s1,satp
    
    // 检查当前SATP寄存器
    uint64 satp_before = r_satp();
    printf("  SATP before: 0x%lx\n", satp_before);
    800027e4:	85a6                	mv	a1,s1
    800027e6:	00002517          	auipc	a0,0x2
    800027ea:	5a250513          	add	a0,a0,1442 # 80004d88 <digits+0x968>
    800027ee:	fa6fe0ef          	jal	80000f94 <printf>
    
    // 初始化内核虚拟内存
    kvminit();
    800027f2:	e3eff0ef          	jal	80001e30 <kvminit>
    ASSERT(kernel_pagetable != 0, "Kernel page table should be created");
    800027f6:	00004597          	auipc	a1,0x4
    800027fa:	9325b583          	ld	a1,-1742(a1) # 80006128 <kernel_pagetable>
    800027fe:	c5d9                	beqz	a1,8000288c <test_virtual_memory+0xd8>
    80002800:	00004717          	auipc	a4,0x4
    80002804:	93470713          	add	a4,a4,-1740 # 80006134 <tests_passed>
    80002808:	431c                	lw	a5,0(a4)
    8000280a:	2785                	addw	a5,a5,1
    8000280c:	c31c                	sw	a5,0(a4)
    
    printf("  Kernel page table created at: 0x%lx\n", (uint64)kernel_pagetable);
    8000280e:	00002517          	auipc	a0,0x2
    80002812:	5ba50513          	add	a0,a0,1466 # 80004dc8 <digits+0x9a8>
    80002816:	f7efe0ef          	jal	80000f94 <printf>
    
    // 激活内核页表
    kvminithart();
    8000281a:	ee2ff0ef          	jal	80001efc <kvminithart>
    8000281e:	18002973          	csrr	s2,satp
    
    uint64 satp_after = r_satp();
    printf("  SATP after: 0x%lx\n", satp_after);
    80002822:	85ca                	mv	a1,s2
    80002824:	00002517          	auipc	a0,0x2
    80002828:	5cc50513          	add	a0,a0,1484 # 80004df0 <digits+0x9d0>
    8000282c:	f68fe0ef          	jal	80000f94 <printf>
    ASSERT(satp_after != satp_before, "SATP should change after activation");
    80002830:	09248663          	beq	s1,s2,800028bc <test_virtual_memory+0x108>
    80002834:	00004497          	auipc	s1,0x4
    80002838:	90048493          	add	s1,s1,-1792 # 80006134 <tests_passed>
    8000283c:	409c                	lw	a5,0(s1)
    8000283e:	2785                	addw	a5,a5,1
    80002840:	c09c                	sw	a5,0(s1)
    
    printf("  After enabling paging...\n");
    80002842:	00002517          	auipc	a0,0x2
    80002846:	5ee50513          	add	a0,a0,1518 # 80004e30 <digits+0xa10>
    8000284a:	f4afe0ef          	jal	80000f94 <printf>
    
    // 测试内核代码仍然可执行
    printf("  Kernel code still executable\n");
    8000284e:	00002517          	auipc	a0,0x2
    80002852:	60250513          	add	a0,a0,1538 # 80004e50 <digits+0xa30>
    80002856:	f3efe0ef          	jal	80000f94 <printf>
    static int test_data = 42;
    ASSERT(test_data == 42, "Kernel data should still be accessible");
    
    // 测试堆栈仍然可用
    int stack_var = 123;
    ASSERT(stack_var == 123, "Stack should still be accessible");
    8000285a:	409c                	lw	a5,0(s1)
    8000285c:	2789                	addw	a5,a5,2
    8000285e:	c09c                	sw	a5,0(s1)
    
    printf("  Virtual memory activation successful\n");
    80002860:	00002517          	auipc	a0,0x2
    80002864:	61050513          	add	a0,a0,1552 # 80004e70 <digits+0xa50>
    80002868:	f2cfe0ef          	jal	80000f94 <printf>
    
    TEST_END("Virtual Memory Activation");
    8000286c:	00002597          	auipc	a1,0x2
    80002870:	4dc58593          	add	a1,a1,1244 # 80004d48 <digits+0x928>
    80002874:	00001517          	auipc	a0,0x1
    80002878:	d2c50513          	add	a0,a0,-724 # 800035a0 <etext+0x5a0>
    8000287c:	f18fe0ef          	jal	80000f94 <printf>
}
    80002880:	60e2                	ld	ra,24(sp)
    80002882:	6442                	ld	s0,16(sp)
    80002884:	64a2                	ld	s1,8(sp)
    80002886:	6902                	ld	s2,0(sp)
    80002888:	6105                	add	sp,sp,32
    8000288a:	8082                	ret
    ASSERT(kernel_pagetable != 0, "Kernel page table should be created");
    8000288c:	0d000693          	li	a3,208
    80002890:	00002617          	auipc	a2,0x2
    80002894:	08860613          	add	a2,a2,136 # 80004918 <digits+0x4f8>
    80002898:	00002597          	auipc	a1,0x2
    8000289c:	50858593          	add	a1,a1,1288 # 80004da0 <digits+0x980>
    800028a0:	00002517          	auipc	a0,0x2
    800028a4:	0b050513          	add	a0,a0,176 # 80004950 <digits+0x530>
    800028a8:	eecfe0ef          	jal	80000f94 <printf>
    800028ac:	00004717          	auipc	a4,0x4
    800028b0:	88470713          	add	a4,a4,-1916 # 80006130 <tests_failed>
    800028b4:	431c                	lw	a5,0(a4)
    800028b6:	2785                	addw	a5,a5,1
    800028b8:	c31c                	sw	a5,0(a4)
    800028ba:	b7d9                	j	80002880 <test_virtual_memory+0xcc>
    ASSERT(satp_after != satp_before, "SATP should change after activation");
    800028bc:	0d900693          	li	a3,217
    800028c0:	00002617          	auipc	a2,0x2
    800028c4:	05860613          	add	a2,a2,88 # 80004918 <digits+0x4f8>
    800028c8:	00002597          	auipc	a1,0x2
    800028cc:	54058593          	add	a1,a1,1344 # 80004e08 <digits+0x9e8>
    800028d0:	00002517          	auipc	a0,0x2
    800028d4:	08050513          	add	a0,a0,128 # 80004950 <digits+0x530>
    800028d8:	ebcfe0ef          	jal	80000f94 <printf>
    800028dc:	00004717          	auipc	a4,0x4
    800028e0:	85470713          	add	a4,a4,-1964 # 80006130 <tests_failed>
    800028e4:	431c                	lw	a5,0(a4)
    800028e6:	2785                	addw	a5,a5,1
    800028e8:	c31c                	sw	a5,0(a4)
    800028ea:	bf59                	j	80002880 <test_virtual_memory+0xcc>

00000000800028ec <run_all_mm_tests>:

/*
 * 运行所有内存管理测试
 */
void run_all_mm_tests(void)
{
    800028ec:	1101                	add	sp,sp,-32
    800028ee:	ec06                	sd	ra,24(sp)
    800028f0:	e822                	sd	s0,16(sp)
    800028f2:	e426                	sd	s1,8(sp)
    800028f4:	e04a                	sd	s2,0(sp)
    800028f6:	1000                	add	s0,sp,32
    printf("\n=== Memory Management Tests ===\n");
    800028f8:	00002517          	auipc	a0,0x2
    800028fc:	5a050513          	add	a0,a0,1440 # 80004e98 <digits+0xa78>
    80002900:	e94fe0ef          	jal	80000f94 <printf>
    
    tests_passed = 0;
    80002904:	00004917          	auipc	s2,0x4
    80002908:	83090913          	add	s2,s2,-2000 # 80006134 <tests_passed>
    8000290c:	00092023          	sw	zero,0(s2)
    tests_failed = 0;
    80002910:	00004497          	auipc	s1,0x4
    80002914:	82048493          	add	s1,s1,-2016 # 80006130 <tests_failed>
    80002918:	0004a023          	sw	zero,0(s1)
    
    // 首先初始化物理内存分配器
    printf("Initializing physical memory allocator...\n");
    8000291c:	00002517          	auipc	a0,0x2
    80002920:	5a450513          	add	a0,a0,1444 # 80004ec0 <digits+0xaa0>
    80002924:	e70fe0ef          	jal	80000f94 <printf>
    pmm_init();
    80002928:	928ff0ef          	jal	80001a50 <pmm_init>
    
    // 运行测试
    test_physical_memory();
    8000292c:	a4fff0ef          	jal	8000237a <test_physical_memory>
    test_pagetable();
    80002930:	e45ff0ef          	jal	80002774 <test_pagetable>
    test_virtual_memory();
    80002934:	e81ff0ef          	jal	800027b4 <test_virtual_memory>
    
    // 输出测试结果
    printf("\n=== Test Results ===\n");
    80002938:	00002517          	auipc	a0,0x2
    8000293c:	5b850513          	add	a0,a0,1464 # 80004ef0 <digits+0xad0>
    80002940:	e54fe0ef          	jal	80000f94 <printf>
    printf("Tests passed: %d\n", tests_passed);
    80002944:	00092583          	lw	a1,0(s2)
    80002948:	00001517          	auipc	a0,0x1
    8000294c:	f0050513          	add	a0,a0,-256 # 80003848 <etext+0x848>
    80002950:	e44fe0ef          	jal	80000f94 <printf>
    printf("Tests failed: %d\n", tests_failed);
    80002954:	408c                	lw	a1,0(s1)
    80002956:	00001517          	auipc	a0,0x1
    8000295a:	f0a50513          	add	a0,a0,-246 # 80003860 <etext+0x860>
    8000295e:	e36fe0ef          	jal	80000f94 <printf>
    
    if (tests_failed == 0) {
    80002962:	409c                	lw	a5,0(s1)
    80002964:	e39d                	bnez	a5,8000298a <run_all_mm_tests+0x9e>
        printf("All memory management tests PASSED!\n");
    80002966:	00002517          	auipc	a0,0x2
    8000296a:	5a250513          	add	a0,a0,1442 # 80004f08 <digits+0xae8>
    8000296e:	e26fe0ef          	jal	80000f94 <printf>
    } else {
        printf("Some tests FAILED!\n");
    }
    
    printf("=== End of Tests ===\n\n");
    80002972:	00002517          	auipc	a0,0x2
    80002976:	5d650513          	add	a0,a0,1494 # 80004f48 <digits+0xb28>
    8000297a:	e1afe0ef          	jal	80000f94 <printf>
    8000297e:	60e2                	ld	ra,24(sp)
    80002980:	6442                	ld	s0,16(sp)
    80002982:	64a2                	ld	s1,8(sp)
    80002984:	6902                	ld	s2,0(sp)
    80002986:	6105                	add	sp,sp,32
    80002988:	8082                	ret
        printf("Some tests FAILED!\n");
    8000298a:	00002517          	auipc	a0,0x2
    8000298e:	5a650513          	add	a0,a0,1446 # 80004f30 <digits+0xb10>
    80002992:	e02fe0ef          	jal	80000f94 <printf>
    80002996:	bff1                	j	80002972 <run_all_mm_tests+0x86>
	...
